/*
 * 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.decompose.lu;

import org.ejml.data.CDenseMatrix64F;


/**
 * 

* An LU decomposition algorithm that originally came from Jama. In general this is faster than * what is in NR since it creates a cache of a column, which makes a big difference in larger * matrices. *

* * @author Peter Abeles */ public class LUDecompositionAlt_CD64 extends LUDecompositionBase_CD64 { /** * This is a modified version of what was found in the JAMA package. The order that it * performs its permutations in is the primary difference from NR * * @param a The matrix that is to be decomposed. Not modified. * @return true If the matrix can be decomposed and false if it can not. */ public boolean decompose( CDenseMatrix64F a ) { decomposeCommonInit(a); double LUcolj[] = vv; for( int j = 0; j < n; j++ ) { // make a copy of the column to avoid cache jumping issues for( int i = 0; i < m; i++) { LUcolj[i*2] = dataLU[i*stride + j*2]; LUcolj[i*2+1] = dataLU[i*stride + j*2+1]; } // Apply previous transformations. for( int i = 0; i < m; i++ ) { int rowIndex = i*stride; // Most of the time is spent in the following dot product. int kmax = i < j ? i : j; double realS = 0.0; double imgS = 0.0; for (int k = 0; k < kmax; k++) { double realD = dataLU[rowIndex+k*2]; double imgD = dataLU[rowIndex+k*2+1]; double realCol = LUcolj[k*2]; double imgCol = LUcolj[k*2+1]; realS += realD*realCol - imgD*imgCol; imgS += realD*imgCol + imgD*realCol; } dataLU[rowIndex+j*2] = LUcolj[i*2] -= realS; dataLU[rowIndex+j*2+1] = LUcolj[i*2+1] -= imgS; } // Find pivot and exchange if necessary. int p = j; double max = mag(LUcolj, p * 2); for (int i = j+1; i < m; i++) { double v = mag(LUcolj, i * 2); if ( v > max) { p = i; max = v; } } if (p != j) { // swap the rows // for (int k = 0; k < n; k++) { // double t = dataLU[p*n + k]; // dataLU[p*n + k] = dataLU[j*n + k]; // dataLU[j*n + k] = t; // } int rowP = p*stride; int rowJ = j*stride; int endP = rowP+stride; for (;rowP < endP; rowP++,rowJ++) { double t = dataLU[rowP]; dataLU[rowP] = dataLU[rowJ]; dataLU[rowJ] = t; } int k = pivot[p]; pivot[p] = pivot[j]; pivot[j] = k; pivsign = -pivsign; } indx[j] = p; // Compute multipliers. if (j < m ) { double realLujj = dataLU[j*stride+j*2]; double imgLujj = dataLU[j*stride+j*2+1]; double magLujj = realLujj*realLujj + imgLujj*imgLujj; if( realLujj != 0 || imgLujj != 0) { for (int i = j+1; i < m; i++) { double realLU = dataLU[i*stride+j*2]; double imagLU = dataLU[i*stride+j*2+1]; dataLU[i*stride+j*2] = (realLU*realLujj + imagLU*imgLujj)/magLujj; dataLU[i*stride+j*2+1] = (imagLU*realLujj - realLU*imgLujj)/magLujj; } } } } return true; } private static double mag( double d[] , int index ) { double r = d[index]; double i = d[index+1]; return r*r + i*i; } }

Ads help maintain this website.