Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/15/09 13:22:07 (15 years ago)
Author:
gkronber
Message:

Moved ALGLIB code into a separate plugin. #783

Location:
trunk/sources/ALGLIB
Files:
1 added
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/sources/ALGLIB/blas.cs

    r2426 r2430  
    22Copyright (c) 2005-2007, Sergey Bochkanov (ALGLIB project).
    33
    4 Redistribution and use in source and binary forms, with or without
    5 modification, are permitted provided that the following conditions are
    6 met:
    7 
    8 - Redistributions of source code must retain the above copyright
    9   notice, this list of conditions and the following disclaimer.
    10 
    11 - Redistributions in binary form must reproduce the above copyright
    12   notice, this list of conditions and the following disclaimer listed
    13   in this license in the documentation and/or other materials
    14   provided with the distribution.
    15 
    16 - Neither the name of the copyright holders nor the names of its
    17   contributors may be used to endorse or promote products derived from
    18   this software without specific prior written permission.
    19 
    20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     4>>> SOURCE LICENSE >>>
     5This program is free software; you can redistribute it and/or modify
     6it under the terms of the GNU General Public License as published by
     7the Free Software Foundation (www.fsf.org); either version 2 of the
     8License, or (at your option) any later version.
     9
     10This program is distributed in the hope that it will be useful,
     11but WITHOUT ANY WARRANTY; without even the implied warranty of
     12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13GNU General Public License for more details.
     14
     15A copy of the GNU General Public License is available at
     16http://www.fsf.org/licensing/licenses
     17
     18>>> END OF LICENSE >>>
    3119*************************************************************************/
    3220
    3321using System;
    3422
    35 class blas
     23namespace alglib
    3624{
    37     public static double vectornorm2(ref double[] x,
    38         int i1,
    39         int i2)
     25    public class blas
    4026    {
    41         double result = 0;
    42         int n = 0;
    43         int ix = 0;
    44         double absxi = 0;
    45         double scl = 0;
    46         double ssq = 0;
    47 
    48         n = i2-i1+1;
    49         if( n<1 )
    50         {
     27        public static double vectornorm2(ref double[] x,
     28            int i1,
     29            int i2)
     30        {
     31            double result = 0;
     32            int n = 0;
     33            int ix = 0;
     34            double absxi = 0;
     35            double scl = 0;
     36            double ssq = 0;
     37
     38            n = i2-i1+1;
     39            if( n<1 )
     40            {
     41                result = 0;
     42                return result;
     43            }
     44            if( n==1 )
     45            {
     46                result = Math.Abs(x[i1]);
     47                return result;
     48            }
     49            scl = 0;
     50            ssq = 1;
     51            for(ix=i1; ix<=i2; ix++)
     52            {
     53                if( x[ix]!=0 )
     54                {
     55                    absxi = Math.Abs(x[ix]);
     56                    if( scl<absxi )
     57                    {
     58                        ssq = 1+ssq*AP.Math.Sqr(scl/absxi);
     59                        scl = absxi;
     60                    }
     61                    else
     62                    {
     63                        ssq = ssq+AP.Math.Sqr(absxi/scl);
     64                    }
     65                }
     66            }
     67            result = scl*Math.Sqrt(ssq);
     68            return result;
     69        }
     70
     71
     72        public static int vectoridxabsmax(ref double[] x,
     73            int i1,
     74            int i2)
     75        {
     76            int result = 0;
     77            int i = 0;
     78            double a = 0;
     79
     80            result = i1;
     81            a = Math.Abs(x[result]);
     82            for(i=i1+1; i<=i2; i++)
     83            {
     84                if( Math.Abs(x[i])>Math.Abs(x[result]) )
     85                {
     86                    result = i;
     87                }
     88            }
     89            return result;
     90        }
     91
     92
     93        public static int columnidxabsmax(ref double[,] x,
     94            int i1,
     95            int i2,
     96            int j)
     97        {
     98            int result = 0;
     99            int i = 0;
     100            double a = 0;
     101
     102            result = i1;
     103            a = Math.Abs(x[result,j]);
     104            for(i=i1+1; i<=i2; i++)
     105            {
     106                if( Math.Abs(x[i,j])>Math.Abs(x[result,j]) )
     107                {
     108                    result = i;
     109                }
     110            }
     111            return result;
     112        }
     113
     114
     115        public static int rowidxabsmax(ref double[,] x,
     116            int j1,
     117            int j2,
     118            int i)
     119        {
     120            int result = 0;
     121            int j = 0;
     122            double a = 0;
     123
     124            result = j1;
     125            a = Math.Abs(x[i,result]);
     126            for(j=j1+1; j<=j2; j++)
     127            {
     128                if( Math.Abs(x[i,j])>Math.Abs(x[i,result]) )
     129                {
     130                    result = j;
     131                }
     132            }
     133            return result;
     134        }
     135
     136
     137        public static double upperhessenberg1norm(ref double[,] a,
     138            int i1,
     139            int i2,
     140            int j1,
     141            int j2,
     142            ref double[] work)
     143        {
     144            double result = 0;
     145            int i = 0;
     146            int j = 0;
     147
     148            System.Diagnostics.Debug.Assert(i2-i1==j2-j1, "UpperHessenberg1Norm: I2-I1<>J2-J1!");
     149            for(j=j1; j<=j2; j++)
     150            {
     151                work[j] = 0;
     152            }
     153            for(i=i1; i<=i2; i++)
     154            {
     155                for(j=Math.Max(j1, j1+i-i1-1); j<=j2; j++)
     156                {
     157                    work[j] = work[j]+Math.Abs(a[i,j]);
     158                }
     159            }
    51160            result = 0;
     161            for(j=j1; j<=j2; j++)
     162            {
     163                result = Math.Max(result, work[j]);
     164            }
    52165            return result;
    53166        }
    54         if( n==1 )
    55         {
    56             result = Math.Abs(x[i1]);
     167
     168
     169        public static void copymatrix(ref double[,] a,
     170            int is1,
     171            int is2,
     172            int js1,
     173            int js2,
     174            ref double[,] b,
     175            int id1,
     176            int id2,
     177            int jd1,
     178            int jd2)
     179        {
     180            int isrc = 0;
     181            int idst = 0;
     182            int i_ = 0;
     183            int i1_ = 0;
     184
     185            if( is1>is2 | js1>js2 )
     186            {
     187                return;
     188            }
     189            System.Diagnostics.Debug.Assert(is2-is1==id2-id1, "CopyMatrix: different sizes!");
     190            System.Diagnostics.Debug.Assert(js2-js1==jd2-jd1, "CopyMatrix: different sizes!");
     191            for(isrc=is1; isrc<=is2; isrc++)
     192            {
     193                idst = isrc-is1+id1;
     194                i1_ = (js1) - (jd1);
     195                for(i_=jd1; i_<=jd2;i_++)
     196                {
     197                    b[idst,i_] = a[isrc,i_+i1_];
     198                }
     199            }
     200        }
     201
     202
     203        public static void inplacetranspose(ref double[,] a,
     204            int i1,
     205            int i2,
     206            int j1,
     207            int j2,
     208            ref double[] work)
     209        {
     210            int i = 0;
     211            int j = 0;
     212            int ips = 0;
     213            int jps = 0;
     214            int l = 0;
     215            int i_ = 0;
     216            int i1_ = 0;
     217
     218            if( i1>i2 | j1>j2 )
     219            {
     220                return;
     221            }
     222            System.Diagnostics.Debug.Assert(i1-i2==j1-j2, "InplaceTranspose error: incorrect array size!");
     223            for(i=i1; i<=i2-1; i++)
     224            {
     225                j = j1+i-i1;
     226                ips = i+1;
     227                jps = j1+ips-i1;
     228                l = i2-i;
     229                i1_ = (ips) - (1);
     230                for(i_=1; i_<=l;i_++)
     231                {
     232                    work[i_] = a[i_+i1_,j];
     233                }
     234                i1_ = (jps) - (ips);
     235                for(i_=ips; i_<=i2;i_++)
     236                {
     237                    a[i_,j] = a[i,i_+i1_];
     238                }
     239                i1_ = (1) - (jps);
     240                for(i_=jps; i_<=j2;i_++)
     241                {
     242                    a[i,i_] = work[i_+i1_];
     243                }
     244            }
     245        }
     246
     247
     248        public static void copyandtranspose(ref double[,] a,
     249            int is1,
     250            int is2,
     251            int js1,
     252            int js2,
     253            ref double[,] b,
     254            int id1,
     255            int id2,
     256            int jd1,
     257            int jd2)
     258        {
     259            int isrc = 0;
     260            int jdst = 0;
     261            int i_ = 0;
     262            int i1_ = 0;
     263
     264            if( is1>is2 | js1>js2 )
     265            {
     266                return;
     267            }
     268            System.Diagnostics.Debug.Assert(is2-is1==jd2-jd1, "CopyAndTranspose: different sizes!");
     269            System.Diagnostics.Debug.Assert(js2-js1==id2-id1, "CopyAndTranspose: different sizes!");
     270            for(isrc=is1; isrc<=is2; isrc++)
     271            {
     272                jdst = isrc-is1+jd1;
     273                i1_ = (js1) - (id1);
     274                for(i_=id1; i_<=id2;i_++)
     275                {
     276                    b[i_,jdst] = a[isrc,i_+i1_];
     277                }
     278            }
     279        }
     280
     281
     282        public static void matrixvectormultiply(ref double[,] a,
     283            int i1,
     284            int i2,
     285            int j1,
     286            int j2,
     287            bool trans,
     288            ref double[] x,
     289            int ix1,
     290            int ix2,
     291            double alpha,
     292            ref double[] y,
     293            int iy1,
     294            int iy2,
     295            double beta)
     296        {
     297            int i = 0;
     298            double v = 0;
     299            int i_ = 0;
     300            int i1_ = 0;
     301
     302            if( !trans )
     303            {
     304               
     305                //
     306                // y := alpha*A*x + beta*y;
     307                //
     308                if( i1>i2 | j1>j2 )
     309                {
     310                    return;
     311                }
     312                System.Diagnostics.Debug.Assert(j2-j1==ix2-ix1, "MatrixVectorMultiply: A and X dont match!");
     313                System.Diagnostics.Debug.Assert(i2-i1==iy2-iy1, "MatrixVectorMultiply: A and Y dont match!");
     314               
     315                //
     316                // beta*y
     317                //
     318                if( beta==0 )
     319                {
     320                    for(i=iy1; i<=iy2; i++)
     321                    {
     322                        y[i] = 0;
     323                    }
     324                }
     325                else
     326                {
     327                    for(i_=iy1; i_<=iy2;i_++)
     328                    {
     329                        y[i_] = beta*y[i_];
     330                    }
     331                }
     332               
     333                //
     334                // alpha*A*x
     335                //
     336                for(i=i1; i<=i2; i++)
     337                {
     338                    i1_ = (ix1)-(j1);
     339                    v = 0.0;
     340                    for(i_=j1; i_<=j2;i_++)
     341                    {
     342                        v += a[i,i_]*x[i_+i1_];
     343                    }
     344                    y[iy1+i-i1] = y[iy1+i-i1]+alpha*v;
     345                }
     346            }
     347            else
     348            {
     349               
     350                //
     351                // y := alpha*A'*x + beta*y;
     352                //
     353                if( i1>i2 | j1>j2 )
     354                {
     355                    return;
     356                }
     357                System.Diagnostics.Debug.Assert(i2-i1==ix2-ix1, "MatrixVectorMultiply: A and X dont match!");
     358                System.Diagnostics.Debug.Assert(j2-j1==iy2-iy1, "MatrixVectorMultiply: A and Y dont match!");
     359               
     360                //
     361                // beta*y
     362                //
     363                if( beta==0 )
     364                {
     365                    for(i=iy1; i<=iy2; i++)
     366                    {
     367                        y[i] = 0;
     368                    }
     369                }
     370                else
     371                {
     372                    for(i_=iy1; i_<=iy2;i_++)
     373                    {
     374                        y[i_] = beta*y[i_];
     375                    }
     376                }
     377               
     378                //
     379                // alpha*A'*x
     380                //
     381                for(i=i1; i<=i2; i++)
     382                {
     383                    v = alpha*x[ix1+i-i1];
     384                    i1_ = (j1) - (iy1);
     385                    for(i_=iy1; i_<=iy2;i_++)
     386                    {
     387                        y[i_] = y[i_] + v*a[i,i_+i1_];
     388                    }
     389                }
     390            }
     391        }
     392
     393
     394        public static double pythag2(double x,
     395            double y)
     396        {
     397            double result = 0;
     398            double w = 0;
     399            double xabs = 0;
     400            double yabs = 0;
     401            double z = 0;
     402
     403            xabs = Math.Abs(x);
     404            yabs = Math.Abs(y);
     405            w = Math.Max(xabs, yabs);
     406            z = Math.Min(xabs, yabs);
     407            if( z==0 )
     408            {
     409                result = w;
     410            }
     411            else
     412            {
     413                result = w*Math.Sqrt(1+AP.Math.Sqr(z/w));
     414            }
    57415            return result;
    58416        }
    59         scl = 0;
    60         ssq = 1;
    61         for(ix=i1; ix<=i2; ix++)
    62         {
    63             if( x[ix]!=0 )
    64             {
    65                 absxi = Math.Abs(x[ix]);
    66                 if( scl<absxi )
    67                 {
    68                     ssq = 1+ssq*AP.Math.Sqr(scl/absxi);
    69                     scl = absxi;
     417
     418
     419        public static void matrixmatrixmultiply(ref double[,] a,
     420            int ai1,
     421            int ai2,
     422            int aj1,
     423            int aj2,
     424            bool transa,
     425            ref double[,] b,
     426            int bi1,
     427            int bi2,
     428            int bj1,
     429            int bj2,
     430            bool transb,
     431            double alpha,
     432            ref double[,] c,
     433            int ci1,
     434            int ci2,
     435            int cj1,
     436            int cj2,
     437            double beta,
     438            ref double[] work)
     439        {
     440            int arows = 0;
     441            int acols = 0;
     442            int brows = 0;
     443            int bcols = 0;
     444            int crows = 0;
     445            int ccols = 0;
     446            int i = 0;
     447            int j = 0;
     448            int k = 0;
     449            int l = 0;
     450            int r = 0;
     451            double v = 0;
     452            int i_ = 0;
     453            int i1_ = 0;
     454
     455           
     456            //
     457            // Setup
     458            //
     459            if( !transa )
     460            {
     461                arows = ai2-ai1+1;
     462                acols = aj2-aj1+1;
     463            }
     464            else
     465            {
     466                arows = aj2-aj1+1;
     467                acols = ai2-ai1+1;
     468            }
     469            if( !transb )
     470            {
     471                brows = bi2-bi1+1;
     472                bcols = bj2-bj1+1;
     473            }
     474            else
     475            {
     476                brows = bj2-bj1+1;
     477                bcols = bi2-bi1+1;
     478            }
     479            System.Diagnostics.Debug.Assert(acols==brows, "MatrixMatrixMultiply: incorrect matrix sizes!");
     480            if( arows<=0 | acols<=0 | brows<=0 | bcols<=0 )
     481            {
     482                return;
     483            }
     484            crows = arows;
     485            ccols = bcols;
     486           
     487            //
     488            // Test WORK
     489            //
     490            i = Math.Max(arows, acols);
     491            i = Math.Max(brows, i);
     492            i = Math.Max(i, bcols);
     493            work[1] = 0;
     494            work[i] = 0;
     495           
     496            //
     497            // Prepare C
     498            //
     499            if( beta==0 )
     500            {
     501                for(i=ci1; i<=ci2; i++)
     502                {
     503                    for(j=cj1; j<=cj2; j++)
     504                    {
     505                        c[i,j] = 0;
     506                    }
     507                }
     508            }
     509            else
     510            {
     511                for(i=ci1; i<=ci2; i++)
     512                {
     513                    for(i_=cj1; i_<=cj2;i_++)
     514                    {
     515                        c[i,i_] = beta*c[i,i_];
     516                    }
     517                }
     518            }
     519           
     520            //
     521            // A*B
     522            //
     523            if( !transa & !transb )
     524            {
     525                for(l=ai1; l<=ai2; l++)
     526                {
     527                    for(r=bi1; r<=bi2; r++)
     528                    {
     529                        v = alpha*a[l,aj1+r-bi1];
     530                        k = ci1+l-ai1;
     531                        i1_ = (bj1) - (cj1);
     532                        for(i_=cj1; i_<=cj2;i_++)
     533                        {
     534                            c[k,i_] = c[k,i_] + v*b[r,i_+i1_];
     535                        }
     536                    }
     537                }
     538                return;
     539            }
     540           
     541            //
     542            // A*B'
     543            //
     544            if( !transa & transb )
     545            {
     546                if( arows*acols<brows*bcols )
     547                {
     548                    for(r=bi1; r<=bi2; r++)
     549                    {
     550                        for(l=ai1; l<=ai2; l++)
     551                        {
     552                            i1_ = (bj1)-(aj1);
     553                            v = 0.0;
     554                            for(i_=aj1; i_<=aj2;i_++)
     555                            {
     556                                v += a[l,i_]*b[r,i_+i1_];
     557                            }
     558                            c[ci1+l-ai1,cj1+r-bi1] = c[ci1+l-ai1,cj1+r-bi1]+alpha*v;
     559                        }
     560                    }
     561                    return;
    70562                }
    71563                else
    72564                {
    73                     ssq = ssq+AP.Math.Sqr(absxi/scl);
    74                 }
    75             }
    76         }
    77         result = scl*Math.Sqrt(ssq);
    78         return result;
    79     }
    80 
    81 
    82     public static int vectoridxabsmax(ref double[] x,
    83         int i1,
    84         int i2)
    85     {
    86         int result = 0;
    87         int i = 0;
    88         double a = 0;
    89 
    90         result = i1;
    91         a = Math.Abs(x[result]);
    92         for(i=i1+1; i<=i2; i++)
    93         {
    94             if( Math.Abs(x[i])>Math.Abs(x[result]) )
    95             {
    96                 result = i;
    97             }
    98         }
    99         return result;
    100     }
    101 
    102 
    103     public static int columnidxabsmax(ref double[,] x,
    104         int i1,
    105         int i2,
    106         int j)
    107     {
    108         int result = 0;
    109         int i = 0;
    110         double a = 0;
    111 
    112         result = i1;
    113         a = Math.Abs(x[result,j]);
    114         for(i=i1+1; i<=i2; i++)
    115         {
    116             if( Math.Abs(x[i,j])>Math.Abs(x[result,j]) )
    117             {
    118                 result = i;
    119             }
    120         }
    121         return result;
    122     }
    123 
    124 
    125     public static int rowidxabsmax(ref double[,] x,
    126         int j1,
    127         int j2,
    128         int i)
    129     {
    130         int result = 0;
    131         int j = 0;
    132         double a = 0;
    133 
    134         result = j1;
    135         a = Math.Abs(x[i,result]);
    136         for(j=j1+1; j<=j2; j++)
    137         {
    138             if( Math.Abs(x[i,j])>Math.Abs(x[i,result]) )
    139             {
    140                 result = j;
    141             }
    142         }
    143         return result;
    144     }
    145 
    146 
    147     public static double upperhessenberg1norm(ref double[,] a,
    148         int i1,
    149         int i2,
    150         int j1,
    151         int j2,
    152         ref double[] work)
    153     {
    154         double result = 0;
    155         int i = 0;
    156         int j = 0;
    157 
    158         System.Diagnostics.Debug.Assert(i2-i1==j2-j1, "UpperHessenberg1Norm: I2-I1<>J2-J1!");
    159         for(j=j1; j<=j2; j++)
    160         {
    161             work[j] = 0;
    162         }
    163         for(i=i1; i<=i2; i++)
    164         {
    165             for(j=Math.Max(j1, j1+i-i1-1); j<=j2; j++)
    166             {
    167                 work[j] = work[j]+Math.Abs(a[i,j]);
    168             }
    169         }
    170         result = 0;
    171         for(j=j1; j<=j2; j++)
    172         {
    173             result = Math.Max(result, work[j]);
    174         }
    175         return result;
    176     }
    177 
    178 
    179     public static void copymatrix(ref double[,] a,
    180         int is1,
    181         int is2,
    182         int js1,
    183         int js2,
    184         ref double[,] b,
    185         int id1,
    186         int id2,
    187         int jd1,
    188         int jd2)
    189     {
    190         int isrc = 0;
    191         int idst = 0;
    192         int i_ = 0;
    193         int i1_ = 0;
    194 
    195         if( is1>is2 | js1>js2 )
    196         {
    197             return;
    198         }
    199         System.Diagnostics.Debug.Assert(is2-is1==id2-id1, "CopyMatrix: different sizes!");
    200         System.Diagnostics.Debug.Assert(js2-js1==jd2-jd1, "CopyMatrix: different sizes!");
    201         for(isrc=is1; isrc<=is2; isrc++)
    202         {
    203             idst = isrc-is1+id1;
    204             i1_ = (js1) - (jd1);
    205             for(i_=jd1; i_<=jd2;i_++)
    206             {
    207                 b[idst,i_] = a[isrc,i_+i1_];
    208             }
    209         }
    210     }
    211 
    212 
    213     public static void inplacetranspose(ref double[,] a,
    214         int i1,
    215         int i2,
    216         int j1,
    217         int j2,
    218         ref double[] work)
    219     {
    220         int i = 0;
    221         int j = 0;
    222         int ips = 0;
    223         int jps = 0;
    224         int l = 0;
    225         int i_ = 0;
    226         int i1_ = 0;
    227 
    228         if( i1>i2 | j1>j2 )
    229         {
    230             return;
    231         }
    232         System.Diagnostics.Debug.Assert(i1-i2==j1-j2, "InplaceTranspose error: incorrect array size!");
    233         for(i=i1; i<=i2-1; i++)
    234         {
    235             j = j1+i-i1;
    236             ips = i+1;
    237             jps = j1+ips-i1;
    238             l = i2-i;
    239             i1_ = (ips) - (1);
    240             for(i_=1; i_<=l;i_++)
    241             {
    242                 work[i_] = a[i_+i1_,j];
    243             }
    244             i1_ = (jps) - (ips);
    245             for(i_=ips; i_<=i2;i_++)
    246             {
    247                 a[i_,j] = a[i,i_+i1_];
    248             }
    249             i1_ = (1) - (jps);
    250             for(i_=jps; i_<=j2;i_++)
    251             {
    252                 a[i,i_] = work[i_+i1_];
    253             }
    254         }
    255     }
    256 
    257 
    258     public static void copyandtranspose(ref double[,] a,
    259         int is1,
    260         int is2,
    261         int js1,
    262         int js2,
    263         ref double[,] b,
    264         int id1,
    265         int id2,
    266         int jd1,
    267         int jd2)
    268     {
    269         int isrc = 0;
    270         int jdst = 0;
    271         int i_ = 0;
    272         int i1_ = 0;
    273 
    274         if( is1>is2 | js1>js2 )
    275         {
    276             return;
    277         }
    278         System.Diagnostics.Debug.Assert(is2-is1==jd2-jd1, "CopyAndTranspose: different sizes!");
    279         System.Diagnostics.Debug.Assert(js2-js1==id2-id1, "CopyAndTranspose: different sizes!");
    280         for(isrc=is1; isrc<=is2; isrc++)
    281         {
    282             jdst = isrc-is1+jd1;
    283             i1_ = (js1) - (id1);
    284             for(i_=id1; i_<=id2;i_++)
    285             {
    286                 b[i_,jdst] = a[isrc,i_+i1_];
    287             }
    288         }
    289     }
    290 
    291 
    292     public static void matrixvectormultiply(ref double[,] a,
    293         int i1,
    294         int i2,
    295         int j1,
    296         int j2,
    297         bool trans,
    298         ref double[] x,
    299         int ix1,
    300         int ix2,
    301         double alpha,
    302         ref double[] y,
    303         int iy1,
    304         int iy2,
    305         double beta)
    306     {
    307         int i = 0;
    308         double v = 0;
    309         int i_ = 0;
    310         int i1_ = 0;
    311 
    312         if( !trans )
    313         {
     565                    for(l=ai1; l<=ai2; l++)
     566                    {
     567                        for(r=bi1; r<=bi2; r++)
     568                        {
     569                            i1_ = (bj1)-(aj1);
     570                            v = 0.0;
     571                            for(i_=aj1; i_<=aj2;i_++)
     572                            {
     573                                v += a[l,i_]*b[r,i_+i1_];
     574                            }
     575                            c[ci1+l-ai1,cj1+r-bi1] = c[ci1+l-ai1,cj1+r-bi1]+alpha*v;
     576                        }
     577                    }
     578                    return;
     579                }
     580            }
    314581           
    315582            //
    316             // y := alpha*A*x + beta*y;
    317             //
    318             if( i1>i2 | j1>j2 )
    319             {
     583            // A'*B
     584            //
     585            if( transa & !transb )
     586            {
     587                for(l=aj1; l<=aj2; l++)
     588                {
     589                    for(r=bi1; r<=bi2; r++)
     590                    {
     591                        v = alpha*a[ai1+r-bi1,l];
     592                        k = ci1+l-aj1;
     593                        i1_ = (bj1) - (cj1);
     594                        for(i_=cj1; i_<=cj2;i_++)
     595                        {
     596                            c[k,i_] = c[k,i_] + v*b[r,i_+i1_];
     597                        }
     598                    }
     599                }
    320600                return;
    321601            }
    322             System.Diagnostics.Debug.Assert(j2-j1==ix2-ix1, "MatrixVectorMultiply: A and X dont match!");
    323             System.Diagnostics.Debug.Assert(i2-i1==iy2-iy1, "MatrixVectorMultiply: A and Y dont match!");
    324602           
    325603            //
    326             // beta*y
    327             //
    328             if( beta==0 )
    329             {
    330                 for(i=iy1; i<=iy2; i++)
    331                 {
    332                     y[i] = 0;
    333                 }
    334             }
    335             else
    336             {
    337                 for(i_=iy1; i_<=iy2;i_++)
    338                 {
    339                     y[i_] = beta*y[i_];
    340                 }
    341             }
    342            
    343             //
    344             // alpha*A*x
    345             //
    346             for(i=i1; i<=i2; i++)
    347             {
    348                 i1_ = (ix1)-(j1);
    349                 v = 0.0;
    350                 for(i_=j1; i_<=j2;i_++)
    351                 {
    352                     v += a[i,i_]*x[i_+i1_];
    353                 }
    354                 y[iy1+i-i1] = y[iy1+i-i1]+alpha*v;
    355             }
    356         }
    357         else
    358         {
    359            
    360             //
    361             // y := alpha*A'*x + beta*y;
    362             //
    363             if( i1>i2 | j1>j2 )
    364             {
    365                 return;
    366             }
    367             System.Diagnostics.Debug.Assert(i2-i1==ix2-ix1, "MatrixVectorMultiply: A and X dont match!");
    368             System.Diagnostics.Debug.Assert(j2-j1==iy2-iy1, "MatrixVectorMultiply: A and Y dont match!");
    369            
    370             //
    371             // beta*y
    372             //
    373             if( beta==0 )
    374             {
    375                 for(i=iy1; i<=iy2; i++)
    376                 {
    377                     y[i] = 0;
    378                 }
    379             }
    380             else
    381             {
    382                 for(i_=iy1; i_<=iy2;i_++)
    383                 {
    384                     y[i_] = beta*y[i_];
    385                 }
    386             }
    387            
    388             //
    389             // alpha*A'*x
    390             //
    391             for(i=i1; i<=i2; i++)
    392             {
    393                 v = alpha*x[ix1+i-i1];
    394                 i1_ = (j1) - (iy1);
    395                 for(i_=iy1; i_<=iy2;i_++)
    396                 {
    397                     y[i_] = y[i_] + v*a[i,i_+i1_];
    398                 }
    399             }
    400         }
    401     }
    402 
    403 
    404     public static double pythag2(double x,
    405         double y)
    406     {
    407         double result = 0;
    408         double w = 0;
    409         double xabs = 0;
    410         double yabs = 0;
    411         double z = 0;
    412 
    413         xabs = Math.Abs(x);
    414         yabs = Math.Abs(y);
    415         w = Math.Max(xabs, yabs);
    416         z = Math.Min(xabs, yabs);
    417         if( z==0 )
    418         {
    419             result = w;
    420         }
    421         else
    422         {
    423             result = w*Math.Sqrt(1+AP.Math.Sqr(z/w));
    424         }
    425         return result;
    426     }
    427 
    428 
    429     public static void matrixmatrixmultiply(ref double[,] a,
    430         int ai1,
    431         int ai2,
    432         int aj1,
    433         int aj2,
    434         bool transa,
    435         ref double[,] b,
    436         int bi1,
    437         int bi2,
    438         int bj1,
    439         int bj2,
    440         bool transb,
    441         double alpha,
    442         ref double[,] c,
    443         int ci1,
    444         int ci2,
    445         int cj1,
    446         int cj2,
    447         double beta,
    448         ref double[] work)
    449     {
    450         int arows = 0;
    451         int acols = 0;
    452         int brows = 0;
    453         int bcols = 0;
    454         int crows = 0;
    455         int ccols = 0;
    456         int i = 0;
    457         int j = 0;
    458         int k = 0;
    459         int l = 0;
    460         int r = 0;
    461         double v = 0;
    462         int i_ = 0;
    463         int i1_ = 0;
    464 
    465        
    466         //
    467         // Setup
    468         //
    469         if( !transa )
    470         {
    471             arows = ai2-ai1+1;
    472             acols = aj2-aj1+1;
    473         }
    474         else
    475         {
    476             arows = aj2-aj1+1;
    477             acols = ai2-ai1+1;
    478         }
    479         if( !transb )
    480         {
    481             brows = bi2-bi1+1;
    482             bcols = bj2-bj1+1;
    483         }
    484         else
    485         {
    486             brows = bj2-bj1+1;
    487             bcols = bi2-bi1+1;
    488         }
    489         System.Diagnostics.Debug.Assert(acols==brows, "MatrixMatrixMultiply: incorrect matrix sizes!");
    490         if( arows<=0 | acols<=0 | brows<=0 | bcols<=0 )
    491         {
    492             return;
    493         }
    494         crows = arows;
    495         ccols = bcols;
    496        
    497         //
    498         // Test WORK
    499         //
    500         i = Math.Max(arows, acols);
    501         i = Math.Max(brows, i);
    502         i = Math.Max(i, bcols);
    503         work[1] = 0;
    504         work[i] = 0;
    505        
    506         //
    507         // Prepare C
    508         //
    509         if( beta==0 )
    510         {
    511             for(i=ci1; i<=ci2; i++)
    512             {
    513                 for(j=cj1; j<=cj2; j++)
    514                 {
    515                     c[i,j] = 0;
    516                 }
    517             }
    518         }
    519         else
    520         {
    521             for(i=ci1; i<=ci2; i++)
    522             {
    523                 for(i_=cj1; i_<=cj2;i_++)
    524                 {
    525                     c[i,i_] = beta*c[i,i_];
    526                 }
    527             }
    528         }
    529        
    530         //
    531         // A*B
    532         //
    533         if( !transa & !transb )
    534         {
    535             for(l=ai1; l<=ai2; l++)
    536             {
    537                 for(r=bi1; r<=bi2; r++)
    538                 {
    539                     v = alpha*a[l,aj1+r-bi1];
    540                     k = ci1+l-ai1;
    541                     i1_ = (bj1) - (cj1);
    542                     for(i_=cj1; i_<=cj2;i_++)
    543                     {
    544                         c[k,i_] = c[k,i_] + v*b[r,i_+i1_];
    545                     }
    546                 }
    547             }
    548             return;
    549         }
    550        
    551         //
    552         // A*B'
    553         //
    554         if( !transa & transb )
    555         {
    556             if( arows*acols<brows*bcols )
    557             {
    558                 for(r=bi1; r<=bi2; r++)
    559                 {
    560                     for(l=ai1; l<=ai2; l++)
    561                     {
    562                         i1_ = (bj1)-(aj1);
    563                         v = 0.0;
    564                         for(i_=aj1; i_<=aj2;i_++)
    565                         {
    566                             v += a[l,i_]*b[r,i_+i1_];
    567                         }
    568                         c[ci1+l-ai1,cj1+r-bi1] = c[ci1+l-ai1,cj1+r-bi1]+alpha*v;
    569                     }
    570                 }
    571                 return;
    572             }
    573             else
    574             {
    575                 for(l=ai1; l<=ai2; l++)
     604            // A'*B'
     605            //
     606            if( transa & transb )
     607            {
     608                if( arows*acols<brows*bcols )
    576609                {
    577610                    for(r=bi1; r<=bi2; r++)
    578611                    {
    579                         i1_ = (bj1)-(aj1);
    580                         v = 0.0;
    581                         for(i_=aj1; i_<=aj2;i_++)
    582                         {
    583                             v += a[l,i_]*b[r,i_+i1_];
    584                         }
    585                         c[ci1+l-ai1,cj1+r-bi1] = c[ci1+l-ai1,cj1+r-bi1]+alpha*v;
    586                     }
    587                 }
    588                 return;
    589             }
    590         }
    591        
    592         //
    593         // A'*B
    594         //
    595         if( transa & !transb )
    596         {
    597             for(l=aj1; l<=aj2; l++)
    598             {
    599                 for(r=bi1; r<=bi2; r++)
    600                 {
    601                     v = alpha*a[ai1+r-bi1,l];
    602                     k = ci1+l-aj1;
    603                     i1_ = (bj1) - (cj1);
    604                     for(i_=cj1; i_<=cj2;i_++)
    605                     {
    606                         c[k,i_] = c[k,i_] + v*b[r,i_+i1_];
    607                     }
    608                 }
    609             }
    610             return;
    611         }
    612        
    613         //
    614         // A'*B'
    615         //
    616         if( transa & transb )
    617         {
    618             if( arows*acols<brows*bcols )
    619             {
    620                 for(r=bi1; r<=bi2; r++)
    621                 {
    622                     for(i=1; i<=crows; i++)
    623                     {
    624                         work[i] = 0.0;
    625                     }
    626                     for(l=ai1; l<=ai2; l++)
    627                     {
    628                         v = alpha*b[r,bj1+l-ai1];
    629                         k = cj1+r-bi1;
    630                         i1_ = (aj1) - (1);
    631                         for(i_=1; i_<=crows;i_++)
    632                         {
    633                             work[i_] = work[i_] + v*a[l,i_+i1_];
    634                         }
    635                     }
    636                     i1_ = (1) - (ci1);
    637                     for(i_=ci1; i_<=ci2;i_++)
    638                     {
    639                         c[i_,k] = c[i_,k] + work[i_+i1_];
    640                     }
    641                 }
    642                 return;
    643             }
    644             else
    645             {
    646                 for(l=aj1; l<=aj2; l++)
    647                 {
    648                     k = ai2-ai1+1;
    649                     i1_ = (ai1) - (1);
    650                     for(i_=1; i_<=k;i_++)
    651                     {
    652                         work[i_] = a[i_+i1_,l];
    653                     }
    654                     for(r=bi1; r<=bi2; r++)
    655                     {
    656                         i1_ = (bj1)-(1);
    657                         v = 0.0;
     612                        for(i=1; i<=crows; i++)
     613                        {
     614                            work[i] = 0.0;
     615                        }
     616                        for(l=ai1; l<=ai2; l++)
     617                        {
     618                            v = alpha*b[r,bj1+l-ai1];
     619                            k = cj1+r-bi1;
     620                            i1_ = (aj1) - (1);
     621                            for(i_=1; i_<=crows;i_++)
     622                            {
     623                                work[i_] = work[i_] + v*a[l,i_+i1_];
     624                            }
     625                        }
     626                        i1_ = (1) - (ci1);
     627                        for(i_=ci1; i_<=ci2;i_++)
     628                        {
     629                            c[i_,k] = c[i_,k] + work[i_+i1_];
     630                        }
     631                    }
     632                    return;
     633                }
     634                else
     635                {
     636                    for(l=aj1; l<=aj2; l++)
     637                    {
     638                        k = ai2-ai1+1;
     639                        i1_ = (ai1) - (1);
    658640                        for(i_=1; i_<=k;i_++)
    659641                        {
    660                             v += work[i_]*b[r,i_+i1_];
    661                         }
    662                         c[ci1+l-aj1,cj1+r-bi1] = c[ci1+l-aj1,cj1+r-bi1]+alpha*v;
    663                     }
    664                 }
    665                 return;
     642                            work[i_] = a[i_+i1_,l];
     643                        }
     644                        for(r=bi1; r<=bi2; r++)
     645                        {
     646                            i1_ = (bj1)-(1);
     647                            v = 0.0;
     648                            for(i_=1; i_<=k;i_++)
     649                            {
     650                                v += work[i_]*b[r,i_+i1_];
     651                            }
     652                            c[ci1+l-aj1,cj1+r-bi1] = c[ci1+l-aj1,cj1+r-bi1]+alpha*v;
     653                        }
     654                    }
     655                    return;
     656                }
    666657            }
    667658        }
Note: See TracChangeset for help on using the changeset viewer.