/*
 * Copyright (c) 2009-2014, Peter Abeles. All Rights Reserved.
 *
 * This file is part of Efficient Java Matrix Library (EJML).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ejml.alg.dense.decomposition.lu;

import org.ejml.alg.dense.decompose.lu.LUDecompositionBase_CD64;
import org.ejml.data.CDenseMatrix64F;


/**
 * This code is inspired from what's in numerical recipes.
 *
 * @author Peter Abeles
 */
public class LUDecompositionNR_CD64 extends LUDecompositionBase_CD64 {

    private static final double TINY = 1.0e-40;


    /**
     * 

* This implementation of LU Decomposition uses the algorithm specified below: * * "Numerical Recipes The Art of Scientific Computing", Third Edition, Pages 48-55
*

* * @param orig The matrix that is to be decomposed. Not modified. * @return true If the matrix can be decomposed and false if it can not. It can * return true and still be singular. */ @Override public boolean decompose( CDenseMatrix64F orig ) { // if( orig.numCols != orig.numRows ) // throw new RuntimeException("Must be square"); decomposeCommonInit(orig); // loop over the rows to get implicit scaling information for( int i = 0; i < m; i++ ) { double big = 0; double bigReal = 0.0; double bigImg = 0.0; for( int j = 0; j < n; j++ ) { double real = dataLU[i*stride +j*2]; double img = dataLU[i*stride +j*2+1]; double temp = real*real + img*img; if( big < temp ) { big = temp; bigReal = real; bigImg = img; } } // see if it is singular if( big == 0.0 ) { bigReal = 1.0; bigImg = 0.0; } // vv = 1.0/big vv[i*2] = bigReal/(big*big); vv[i*2+1] = -bigImg/(big*big); } // outermost kij loop for( int k = 0; k < n; k++ ) { int imax=-1; // start search by row for largest pivot element double big = 0.0; for( int i=k; i< m; i++ ) { double luReal = dataLU[i*stride + k*2]; double luImg = dataLU[i*stride + k*2 + 1]; double vvReal = vv[i*2]; double vvImg = vv[i*2+1]; // double temp = vv[i*2]* dataLU[i* n +k ]; double tmpReal = luReal*vvReal - luImg*vvImg; double tmpImg = luImg*vvReal + luReal*vvReal; double tmpMag = tmpReal*tmpReal + tmpImg*tmpImg; if( tmpMag > big ) { big = tmpMag; imax=i; } } // see if it is singular if( imax < 0 ) { indx[k] = -1; return true; } else { // check to see if rows need to be interchanged if( k != imax ) { int imax_n = imax*stride; int k_n = k*stride; int end = k_n+n*2; // j=0:n-1 for( ; k_n < end; imax_n+=2,k_n+=2) { double tempReal = dataLU[imax_n]; double tempImg = dataLU[imax_n+1]; dataLU[imax_n] = dataLU[k_n]; dataLU[imax_n+1] = dataLU[k_n+1]; dataLU[k_n] = tempReal; dataLU[k_n+1] = tempImg; } pivsign = -pivsign; vv[imax*2] = vv[k*2]; vv[imax*2+1] = vv[k*2+1]; int z = pivot[imax]; pivot[imax] = pivot[k]; pivot[k] = z; } indx[k] = imax; // for some applications it is better to have this set to tiny even though // it is singular. see the book double element_kk_real = dataLU[k*stride +k*2]; double element_kk_img = dataLU[k*stride +k*2+1]; double mag = element_kk_real*element_kk_real + element_kk_img*element_kk_img; if( mag == 0.0) { dataLU[k*stride +k*2] = element_kk_real = TINY; dataLU[k*stride +k*2+1] = element_kk_img = 0; } double element_kk_norm2 = element_kk_real*element_kk_real + element_kk_img*element_kk_img; // the large majority of the processing time is spent in the code below for( int i =k+1; i < m; i++ ) { int i_n=i*stride; // divide the pivot element double luReal = dataLU[i_n + k*2]; double luImg = dataLU[i_n + k*2+1]; double tmpReal = (luReal*element_kk_real + luImg*element_kk_img)/element_kk_norm2; double tmpImg = (luImg*element_kk_real - luReal*element_kk_img)/element_kk_norm2; dataLU[i_n + k*2] = tmpReal; dataLU[i_n + k*2+1] = tmpImg; int k_n = k*stride + k*2+2; int end = i_n+n*2; i_n += k*2+2; // reduce remaining submatrix // j = k+1:n-1 for( ; i_n

Ads help maintain this website.