All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cern.colt.matrix.tfcomplex.impl.DenseFComplexMatrix1D Maven / Gradle / Ivy

Go to download

Parallel Colt is a multithreaded version of Colt - a library for high performance scientific computing in Java. It contains efficient algorithms for data analysis, linear algebra, multi-dimensional arrays, Fourier transforms, statistics and histogramming.

The newest version!
/*
Copyright (C) 1999 CERN - European Organization for Nuclear Research.
Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose 
is hereby granted without fee, provided that the above copyright notice appear in all copies and 
that both that copyright notice and this permission notice appear in supporting documentation. 
CERN makes no representations about the suitability of this software for any purpose. 
It is provided "as is" without expressed or implied warranty.
 */
package cern.colt.matrix.tfcomplex.impl;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import cern.colt.list.tint.IntArrayList;
import cern.colt.matrix.tfcomplex.FComplexMatrix1D;
import cern.colt.matrix.tfcomplex.FComplexMatrix2D;
import cern.colt.matrix.tfcomplex.FComplexMatrix3D;
import cern.colt.matrix.tfloat.FloatMatrix1D;
import cern.colt.matrix.tfloat.impl.DenseFloatMatrix1D;
import cern.jet.math.tfcomplex.FComplex;
import cern.jet.math.tfcomplex.FComplexFunctions;
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
import edu.emory.mathcs.utils.ConcurrencyUtils;

/**
 * Dense 1-d matrix (aka vector) holding complex elements.
 * 

* Internally holds one single contiguous one-dimensional array. Complex data is * represented by 2 float values in sequence, i.e. elements[zero + 2 * k * * stride] constitute real part and elements[zero + 2 * k * stride + 1] * constitute imaginary part (k=0,...,size()-1). * * @author Piotr Wendykier ([email protected]) * */ public class DenseFComplexMatrix1D extends FComplexMatrix1D { private static final long serialVersionUID = 1L; private FloatFFT_1D fft; /** * The elements of this matrix. Complex data is represented by 2 float * values in sequence, i.e. elements[zero + 2 * k * stride] constitute real * part and elements[zero + 2 * k * stride] constitute imaginary part * (k=0,...,size()-1). */ protected float[] elements; /** * Constructs a matrix with a copy of the given values. The values are * copied. So subsequent changes in values are not reflected in the * matrix, and vice-versa. Due to the fact that complex data is represented * by 2 float values in sequence: the real and imaginary parts, the size of * new matrix will be equal to values.length / 2. * * @param values * The values to be filled into the new matrix. */ public DenseFComplexMatrix1D(float[] values) { this(values.length / 2); assign(values); } /** * Constructs a complex matrix with the same size as realPart * matrix and fills the real part of this matrix with elements of * realPart. * * @param realPart * a real matrix whose elements become a real part of this matrix * @throws IllegalArgumentException * if size<0. */ public DenseFComplexMatrix1D(FloatMatrix1D realPart) { this((int) realPart.size()); assignReal(realPart); } /** * Constructs a matrix with a given number of cells. All entries are * initially 0. * * @param size * the number of cells the matrix shall have. * @throws IllegalArgumentException * if size<0. */ public DenseFComplexMatrix1D(int size) { setUp(size, 0, 2); this.isNoView = true; this.elements = new float[2 * size]; } /** * Constructs a matrix with the given parameters. * * @param size * the number of cells the matrix shall have. * @param elements * the cells. * @param zero * the index of the first element. * @param stride * the number of indexes between any two elements, i.e. * index(i+1)-index(i). * @param isNoView * if false then the view is constructed * @throws IllegalArgumentException * if size<0. */ public DenseFComplexMatrix1D(int size, float[] elements, int zero, int stride, boolean isNoView) { setUp(size, zero, stride); this.elements = elements; this.isNoView = isNoView; } public float[] aggregate(final cern.colt.function.tfcomplex.FComplexFComplexFComplexFunction aggr, final cern.colt.function.tfcomplex.FComplexFComplexFunction f) { float[] b = new float[2]; if (size == 0) { b[0] = Float.NaN; b[1] = Float.NaN; return b; } float[] a = null; int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Callable() { public float[] call() throws Exception { int idx = zero + firstIdx * stride; float[] a = f.apply(new float[] { elements[idx], elements[idx + 1] }); for (int i = firstIdx + 1; i < lastIdx; i++) { idx += stride; a = aggr.apply(a, f.apply(new float[] { elements[idx], elements[idx + 1] })); } return a; } }); } a = ConcurrencyUtils.waitForCompletion(futures, aggr); } else { a = f.apply(new float[] { elements[zero], elements[zero + 1] }); int idx = zero; for (int i = 1; i < size; i++) { idx += stride; a = aggr.apply(a, f.apply(new float[] { elements[idx], elements[idx + 1] })); } } return a; } public float[] aggregate(final FComplexMatrix1D other, final cern.colt.function.tfcomplex.FComplexFComplexFComplexFunction aggr, final cern.colt.function.tfcomplex.FComplexFComplexFComplexFunction f) { if (!(other instanceof DenseFComplexMatrix1D)) { return super.aggregate(other, aggr, f); } checkSize(other); if (size == 0) { float[] b = new float[2]; b[0] = Float.NaN; b[1] = Float.NaN; return b; } final int zeroOther = (int) other.index(0); final int strideOther = other.stride(); final float[] elemsOther = (float[]) other.elements(); float[] a = null; int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Callable() { public float[] call() throws Exception { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; float[] a = f.apply(new float[] { elements[idx], elements[idx + 1] }, new float[] { elemsOther[idxOther], elemsOther[idxOther + 1] }); for (int i = firstIdx + 1; i < lastIdx; i++) { idx += stride; idxOther += strideOther; a = aggr.apply(a, f.apply(new float[] { elements[idx], elements[idx + 1] }, new float[] { elemsOther[idxOther], elemsOther[idxOther + 1] })); } return a; } }); } a = ConcurrencyUtils.waitForCompletion(futures, aggr); } else { int idx = zero; int idxOther = zeroOther; a = f.apply(new float[] { elements[zero], elements[zero + 1] }, new float[] { elemsOther[zeroOther], elemsOther[zeroOther + 1] }); for (int i = 1; i < size; i++) { idx += stride; idxOther += strideOther; a = aggr.apply(a, f.apply(new float[] { elements[idx], elements[idx + 1] }, new float[] { elemsOther[idxOther], elemsOther[idxOther + 1] })); } } return a; } public FComplexMatrix1D assign(final cern.colt.function.tfcomplex.FComplexFComplexFunction function) { if (this.elements == null) throw new InternalError(); if (function instanceof cern.jet.math.tfcomplex.FComplexMult) { float[] multiplicator = ((cern.jet.math.tfcomplex.FComplexMult) function).multiplicator; if (multiplicator[0] == 1 && multiplicator[1] == 0) return this; } int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { float[] tmp = new float[2]; int idx = zero + firstIdx * stride; if (function instanceof cern.jet.math.tfcomplex.FComplexMult) { float[] multiplicator = ((cern.jet.math.tfcomplex.FComplexMult) function).multiplicator; for (int k = firstIdx; k < lastIdx; k++) { elements[idx] = elements[idx] * multiplicator[0] - elements[idx + 1] * multiplicator[1]; elements[idx + 1] = elements[idx + 1] * multiplicator[0] + elements[idx] * multiplicator[1]; idx += stride; } } else { for (int k = firstIdx; k < lastIdx; k++) { tmp[0] = elements[idx]; tmp[1] = elements[idx + 1]; tmp = function.apply(tmp); elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; } } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { float[] tmp = new float[2]; int idx = zero; if (function instanceof cern.jet.math.tfcomplex.FComplexMult) { float[] multiplicator = ((cern.jet.math.tfcomplex.FComplexMult) function).multiplicator; for (int k = 0; k < size; k++) { elements[idx] = elements[idx] * multiplicator[0] - elements[idx + 1] * multiplicator[1]; elements[idx + 1] = elements[idx + 1] * multiplicator[0] + elements[idx] * multiplicator[1]; idx += stride; } } else { for (int k = 0; k < size; k++) { tmp[0] = elements[idx]; tmp[1] = elements[idx + 1]; tmp = function.apply(tmp); elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; } } } return this; } public FComplexMatrix1D assign(final cern.colt.function.tfcomplex.FComplexProcedure cond, final cern.colt.function.tfcomplex.FComplexFComplexFunction function) { int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { float[] elem = new float[2]; int idx = zero + firstIdx * stride; for (int i = firstIdx; i < lastIdx; i++) { elem[0] = elements[idx]; elem[1] = elements[idx + 1]; if (cond.apply(elem) == true) { elem = function.apply(elem); elements[idx] = elem[0]; elements[idx + 1] = elem[1]; } idx += stride; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { float[] elem = new float[2]; int idx = zero; for (int i = 0; i < size; i++) { elem[0] = elements[idx]; elem[1] = elements[idx + 1]; if (cond.apply(elem) == true) { elem = function.apply(elem); elements[idx] = elem[0]; elements[idx + 1] = elem[1]; } idx += stride; } } return this; } public FComplexMatrix1D assign(final cern.colt.function.tfcomplex.FComplexProcedure cond, final float[] value) { int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { float[] elem = new float[2]; int idx = zero + firstIdx * stride; for (int i = firstIdx; i < lastIdx; i++) { elem[0] = elements[idx]; elem[1] = elements[idx + 1]; if (cond.apply(elem) == true) { elements[idx] = value[0]; elements[idx + 1] = value[1]; } idx += stride; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { float[] elem = new float[2]; int idx = zero; for (int i = 0; i < size; i++) { elem[0] = elements[idx]; elem[1] = elements[idx + 1]; if (cond.apply(elem) == true) { elements[idx] = value[0]; elements[idx + 1] = value[1]; } idx += stride; } } return this; } public FComplexMatrix1D assign(final cern.colt.function.tfcomplex.FComplexRealFunction function) { if (this.elements == null) throw new InternalError(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; if (function == FComplexFunctions.abs) { for (int k = firstIdx; k < lastIdx; k++) { float absX = Math.abs(elements[idx]); float absY = Math.abs(elements[idx + 1]); if (absX == 0.0 && absY == 0.0) { elements[idx] = 0; } else if (absX >= absY) { float d = elements[idx + 1] / elements[idx]; elements[idx] = absX * (float) Math.sqrt(1.0 + d * d); } else { float d = elements[idx] / elements[idx + 1]; elements[idx] = absY * (float) Math.sqrt(1.0 + d * d); } elements[idx + 1] = 0; idx += stride; } } else { float[] tmp = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { tmp[0] = elements[idx]; tmp[1] = elements[idx + 1]; tmp[0] = function.apply(tmp); elements[idx] = tmp[0]; elements[idx + 1] = 0; idx += stride; } } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; if (function == FComplexFunctions.abs) { for (int k = 0; k < size; k++) { float absX = Math.abs(elements[idx]); float absY = Math.abs(elements[idx + 1]); if (absX == 0.0 && absY == 0.0) { elements[idx] = 0; } else if (absX >= absY) { float d = elements[idx + 1] / elements[idx]; elements[idx] = absX * (float) Math.sqrt(1.0 + d * d); } else { float d = elements[idx] / elements[idx + 1]; elements[idx] = absY * (float) Math.sqrt(1.0 + d * d); } elements[idx + 1] = 0; idx += stride; } } else { float[] tmp = new float[2]; for (int k = 0; k < size; k++) { tmp[0] = elements[idx]; tmp[1] = elements[idx + 1]; tmp[0] = function.apply(tmp); elements[idx] = tmp[0]; elements[idx + 1] = 0; idx += stride; } } } return this; } public FComplexMatrix1D assign(FComplexMatrix1D source) { if (!(source instanceof DenseFComplexMatrix1D)) { return super.assign(source); } DenseFComplexMatrix1D other = (DenseFComplexMatrix1D) source; if (other == this) return this; checkSize(other); if (isNoView && other.isNoView) { // quickest System.arraycopy(other.elements, 0, this.elements, 0, this.elements.length); return this; } if (haveSharedCells(other)) { FComplexMatrix1D c = other.copy(); if (!(c instanceof DenseFComplexMatrix1D)) { // should not happen return super.assign(source); } other = (DenseFComplexMatrix1D) c; } final float[] elemsOther = other.elements; if (elements == null || elemsOther == null) throw new InternalError(); final int strideOther = other.stride; final int zeroOther = (int) other.index(0); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int k = firstIdx; k < lastIdx; k++) { elements[idx] = elemsOther[idxOther]; elements[idx + 1] = elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; for (int k = 0; k < size; k++) { elements[idx] = elemsOther[idxOther]; elements[idx + 1] = elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } return this; } public FComplexMatrix1D assign(FComplexMatrix1D y, final cern.colt.function.tfcomplex.FComplexFComplexFComplexFunction function) { if (!(y instanceof DenseFComplexMatrix1D)) { return super.assign(y, function); } checkSize(y); final float[] elemsOther = (float[]) y.elements(); final int zeroOther = (int) y.index(0); final int strideOther = y.stride(); if (elements == null || elemsOther == null) throw new InternalError(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; if (function == cern.jet.math.tfcomplex.FComplexFunctions.plus) { for (int k = firstIdx; k < lastIdx; k++) { elements[idx] += elemsOther[idxOther]; elements[idx + 1] += elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.minus) { for (int k = firstIdx; k < lastIdx; k++) { elements[idx] -= elemsOther[idxOther]; elements[idx + 1] -= elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.div) { float[] tmp = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { float re = elemsOther[idxOther]; float im = elemsOther[idxOther + 1]; float scalar; if (Math.abs(re) >= Math.abs(im)) { scalar = (float) (1.0 / (re + im * (im / re))); tmp[0] = scalar * (elements[idx] + elements[idx + 1] * (im / re)); tmp[1] = scalar * (elements[idx + 1] - elements[idx] * (im / re)); } else { scalar = (float) (1.0 / (re * (re / im) + im)); tmp[0] = scalar * (elements[idx] * (re / im) + elements[idx + 1]); tmp[1] = scalar * (elements[idx + 1] * (re / im) - elements[idx]); } elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.mult) { float[] tmp = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] - elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = elements[idx + 1] * elemsOther[idxOther] + elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.multConjFirst) { float[] tmp = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = -elements[idx + 1] * elemsOther[idxOther] + elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.multConjSecond) { float[] tmp = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = elements[idx + 1] * elemsOther[idxOther] - elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else { float[] tmp1 = new float[2]; float[] tmp2 = new float[2]; for (int k = firstIdx; k < lastIdx; k++) { tmp1[0] = elements[idx]; tmp1[1] = elements[idx + 1]; tmp2[0] = elemsOther[idxOther]; tmp2[1] = elemsOther[idxOther + 1]; tmp1 = function.apply(tmp1, tmp2); elements[idx] = tmp1[0]; elements[idx + 1] = tmp1[1]; idx += stride; idxOther += strideOther; } } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; if (function == cern.jet.math.tfcomplex.FComplexFunctions.plus) { for (int k = 0; k < size; k++) { elements[idx] += elemsOther[idxOther]; elements[idx + 1] += elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.minus) { for (int k = 0; k < size; k++) { elements[idx] -= elemsOther[idxOther]; elements[idx + 1] -= elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.div) { float[] tmp = new float[2]; for (int k = 0; k < size; k++) { float re = elemsOther[idxOther]; float im = elemsOther[idxOther + 1]; float scalar; if (Math.abs(re) >= Math.abs(im)) { scalar = (float) (1.0 / (re + im * (im / re))); tmp[0] = scalar * (elements[idx] + elements[idx + 1] * (im / re)); tmp[1] = scalar * (elements[idx + 1] - elements[idx] * (im / re)); } else { scalar = (float) (1.0 / (re * (re / im) + im)); tmp[0] = scalar * (elements[idx] * (re / im) + elements[idx + 1]); tmp[1] = scalar * (elements[idx + 1] * (re / im) - elements[idx]); } elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.mult) { float[] tmp = new float[2]; for (int k = 0; k < size; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] - elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = elements[idx + 1] * elemsOther[idxOther] + elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.multConjFirst) { float[] tmp = new float[2]; for (int k = 0; k < size; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = -elements[idx + 1] * elemsOther[idxOther] + elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else if (function == cern.jet.math.tfcomplex.FComplexFunctions.multConjSecond) { float[] tmp = new float[2]; for (int k = 0; k < size; k++) { tmp[0] = elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; tmp[1] = elements[idx + 1] * elemsOther[idxOther] - elements[idx] * elemsOther[idxOther + 1]; elements[idx] = tmp[0]; elements[idx + 1] = tmp[1]; idx += stride; idxOther += strideOther; } } else { float[] tmp1 = new float[2]; float[] tmp2 = new float[2]; for (int k = 0; k < size; k++) { tmp1[0] = elements[idx]; tmp1[1] = elements[idx + 1]; tmp2[0] = elemsOther[idxOther]; tmp2[1] = elemsOther[idxOther + 1]; tmp1 = function.apply(tmp1, tmp2); elements[idx] = tmp1[0]; elements[idx + 1] = tmp1[1]; idx += stride; idxOther += strideOther; } } } return this; } public FComplexMatrix1D assign(final float re, final float im) { int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; for (int k = firstIdx; k < lastIdx; k++) { elements[idx] = re; elements[idx + 1] = im; idx += stride; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; for (int i = 0; i < size; i++) { this.elements[idx] = re; this.elements[idx + 1] = im; idx += stride; } } return this; } public FComplexMatrix1D assign(float[] values) { if (isNoView) { if (values.length != 2 * size) throw new IllegalArgumentException("The length of values[] must be equal to 2*size()=" + 2 * size()); System.arraycopy(values, 0, this.elements, 0, values.length); } else { super.assign(values); } return this; } public FComplexMatrix1D assignImaginary(final FloatMatrix1D other) { if (!(other instanceof DenseFloatMatrix1D)) { return super.assignImaginary(other); } checkSize(other); final int zeroOther = (int) other.index(0); final int strideOther = other.stride(); final float[] elemsOther = (float[]) other.elements(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int i = firstIdx; i < lastIdx; i++) { elements[idx + 1] = elemsOther[idxOther]; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; for (int i = 0; i < size; i++) { elements[idx + 1] = elemsOther[idxOther]; idx += stride; idxOther += strideOther; } } return this; } public FComplexMatrix1D assignReal(final FloatMatrix1D other) { if (!(other instanceof DenseFloatMatrix1D)) { return super.assignReal(other); } checkSize(other); final int zeroOther = (int) other.index(0); final int strideOther = other.stride(); final float[] elemsOther = (float[]) other.elements(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int i = firstIdx; i < lastIdx; i++) { elements[idx] = elemsOther[idxOther]; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; for (int i = 0; i < size; i++) { elements[idx] = elemsOther[idxOther]; idx += stride; idxOther += strideOther; } } return this; } /** * Computes the discrete Fourier transform (DFT) of this matrix. Throws * IllegalArgumentException if the size of this matrix is not a power of 2 * number. */ public void fft() { int oldNthreads = ConcurrencyUtils.getNumberOfThreads(); ConcurrencyUtils.setNumberOfThreads(ConcurrencyUtils.nextPow2(oldNthreads)); if (fft == null) { fft = new FloatFFT_1D(size); } if (isNoView) { fft.complexForward(elements); } else { FComplexMatrix1D copy = this.copy(); fft.complexForward((float[]) copy.elements()); this.assign((float[]) copy.elements()); } ConcurrencyUtils.setNumberOfThreads(oldNthreads); } public float[] elements() { return elements; } public FloatMatrix1D getImaginaryPart() { final DenseFloatMatrix1D Im = new DenseFloatMatrix1D(size); final float[] elemsOther = Im.elements(); final int zeroOther = (int) Im.index(0); final int strideOther = Im.stride(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int k = firstIdx; k < lastIdx; k++) { elemsOther[idxOther] = elements[idx + 1]; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; for (int i = 0; i < size; i++) { elemsOther[idxOther] = elements[idx + 1]; idx += stride; idxOther += strideOther; } } return Im; } public void getNonZeros(final IntArrayList indexList, final ArrayList valueList) { indexList.clear(); valueList.clear(); int s = (int) size(); int idx = zero; for (int k = 0; k < s; k++) { float[] value = new float[2]; value[0] = elements[idx]; value[1] = elements[idx + 1]; if (value[0] != 0 || value[1] != 0) { indexList.add(k); valueList.add(value); } idx += stride; } } public float[] getQuick(int index) { int idx = zero + index * stride; return new float[] { elements[idx], elements[idx + 1] }; } public FloatMatrix1D getRealPart() { final DenseFloatMatrix1D R = new DenseFloatMatrix1D(size); final float[] elemsOther = R.elements(); final int zeroOther = (int) R.index(0); final int strideOther = R.stride(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int k = firstIdx; k < lastIdx; k++) { elemsOther[idxOther] = elements[idx]; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; for (int i = 0; i < size; i++) { elemsOther[idxOther] = elements[idx]; idx += stride; idxOther += strideOther; } } return R; } /** * Computes the inverse of the discrete Fourier transform (IDFT) of this * matrix. Throws IllegalArgumentException if the size of this matrix is not * a power of 2 number. * * @param scale * if true, then scaling is performed. */ public void ifft(boolean scale) { int oldNthreads = ConcurrencyUtils.getNumberOfThreads(); ConcurrencyUtils.setNumberOfThreads(ConcurrencyUtils.nextPow2(oldNthreads)); if (fft == null) { fft = new FloatFFT_1D(size); } if (isNoView) { fft.complexInverse(elements, scale); } else { FComplexMatrix1D copy = this.copy(); fft.complexInverse((float[]) copy.elements(), scale); this.assign((float[]) copy.elements()); } ConcurrencyUtils.setNumberOfThreads(oldNthreads); } public FComplexMatrix1D like(int size) { return new DenseFComplexMatrix1D(size); } public FComplexMatrix2D like2D(int rows, int columns) { return new DenseFComplexMatrix2D(rows, columns); } public FComplexMatrix2D reshape(final int rows, final int columns) { if (rows * columns != size) { throw new IllegalArgumentException("rows*columns != size"); } FComplexMatrix2D M = new DenseFComplexMatrix2D(rows, columns); final float[] elemsOther = (float[]) M.elements(); final int zeroOther = (int) M.index(0, 0); final int rowStrideOther = M.rowStride(); final int columnStrideOther = M.columnStride(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = columns / nthreads; for (int j = 0; j < nthreads; j++) { final int firstColumn = j * k; final int lastColumn = (j == nthreads - 1) ? columns : firstColumn + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx; int idxOther; for (int c = firstColumn; c < lastColumn; c++) { idxOther = zeroOther + c * columnStrideOther; idx = zero + (c * rows) * stride; for (int r = 0; r < rows; r++) { elemsOther[idxOther] = elements[idx]; elemsOther[idxOther + 1] = elements[idx + 1]; idxOther += rowStrideOther; idx += stride; } } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idxOther; int idx = zero; for (int c = 0; c < columns; c++) { idxOther = zeroOther + c * columnStrideOther; for (int r = 0; r < rows; r++) { elemsOther[idxOther] = elements[idx]; elemsOther[idxOther + 1] = elements[idx + 1]; idxOther += rowStrideOther; idx += stride; } } } return M; } public FComplexMatrix3D reshape(final int slices, final int rows, final int columns) { if (slices * rows * columns != size) { throw new IllegalArgumentException("slices*rows*columns != size"); } FComplexMatrix3D M = new DenseFComplexMatrix3D(slices, rows, columns); final float[] elemsOther = (float[]) M.elements(); final int zeroOther = (int) M.index(0, 0, 0); final int sliceStrideOther = M.sliceStride(); final int rowStrideOther = M.rowStride(); final int columnStrideOther = M.columnStride(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = slices / nthreads; for (int j = 0; j < nthreads; j++) { final int firstSlice = j * k; final int lastSlice = (j == nthreads - 1) ? slices : firstSlice + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx; int idxOther; for (int s = firstSlice; s < lastSlice; s++) { for (int c = 0; c < columns; c++) { idxOther = zeroOther + s * sliceStrideOther + c * columnStrideOther; idx = zero + (s * rows * columns + c * rows) * stride; for (int r = 0; r < rows; r++) { elemsOther[idxOther] = elements[idx]; elemsOther[idxOther + 1] = elements[idx + 1]; idxOther += rowStrideOther; idx += stride; } } } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idxOther; int idx = zero; for (int s = 0; s < slices; s++) { for (int c = 0; c < columns; c++) { idxOther = zeroOther + s * sliceStrideOther + c * columnStrideOther; for (int r = 0; r < rows; r++) { elemsOther[idxOther] = elements[idx]; elemsOther[idxOther + 1] = elements[idx + 1]; idxOther += rowStrideOther; idx += stride; } } } } return M; } public void setQuick(int index, float re, float im) { int idx = zero + index * stride; this.elements[idx] = re; this.elements[idx + 1] = im; } public void setQuick(int index, float[] value) { int idx = zero + index * stride; this.elements[idx] = value[0]; this.elements[idx + 1] = value[1]; } public void swap(FComplexMatrix1D other) { if (!(other instanceof DenseFComplexMatrix1D)) { super.swap(other); } DenseFComplexMatrix1D y = (DenseFComplexMatrix1D) other; if (y == this) return; checkSize(y); final float[] elemsOther = y.elements; if (elements == null || elemsOther == null) throw new InternalError(); final int strideOther = y.stride; final int zeroOther = (int) y.index(0); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Runnable() { public void run() { int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; float tmp; for (int k = firstIdx; k < lastIdx; k++) { tmp = elements[idx]; elements[idx] = elemsOther[idxOther]; elemsOther[idxOther] = tmp; tmp = elements[idx + 1]; elements[idx + 1] = elemsOther[idxOther + 1]; elemsOther[idxOther + 1] = tmp; idx += stride; idxOther += strideOther; } } }); } ConcurrencyUtils.waitForCompletion(futures); } else { int idx = zero; int idxOther = zeroOther; float tmp; for (int k = 0; k < size; k++) { tmp = elements[idx]; elements[idx] = elemsOther[idxOther]; elemsOther[idxOther] = tmp; tmp = elements[idx + 1]; elements[idx + 1] = elemsOther[idxOther + 1]; elemsOther[idxOther + 1] = tmp; idx += stride; idxOther += strideOther; } } } public void toArray(float[] values) { if (values.length < 2 * size) throw new IllegalArgumentException("values too small"); if (isNoView) System.arraycopy(this.elements, 0, values, 0, this.elements.length); else super.toArray(values); } public float[] zDotProduct(final FComplexMatrix1D y, final int from, int length) { int size = (int) size(); if (from < 0 || length <= 0) return new float[] { 0, 0 }; int tail = from + length; if (size < tail) tail = size; if (y.size() < tail) tail = (int) y.size(); length = tail - from; final float[] elemsOther = (float[]) y.elements(); if (elements == null || elemsOther == null) throw new InternalError(); final int strideOther = y.stride(); final int zero = (int) index(from); final int zeroOther = (int) y.index(from); int nthreads = ConcurrencyUtils.getNumberOfThreads(); float[] sum = new float[2]; if ((nthreads > 1) && (length >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, length); Future[] futures = new Future[nthreads]; float[][] results = new float[nthreads][2]; int k = length / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? length : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Callable() { public float[] call() throws Exception { float[] sum = new float[2]; int idx = zero + firstIdx * stride; int idxOther = zeroOther + firstIdx * strideOther; for (int k = firstIdx; k < lastIdx; k++) { sum[0] += elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; sum[1] += elements[idx + 1] * elemsOther[idxOther] - elements[idx] * elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } return sum; } }); } try { for (int j = 0; j < nthreads; j++) { results[j] = (float[]) futures[j].get(); } sum = results[0]; for (int j = 1; j < nthreads; j++) { sum = FComplex.plus(sum, results[j]); } } catch (ExecutionException ex) { ex.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } else { int idx = zero; int idxOther = zeroOther; for (int k = 0; k < length; k++) { sum[0] += elements[idx] * elemsOther[idxOther] + elements[idx + 1] * elemsOther[idxOther + 1]; sum[1] += elements[idx + 1] * elemsOther[idxOther] - elements[idx] * elemsOther[idxOther + 1]; idx += stride; idxOther += strideOther; } } return sum; } public float[] zSum() { float[] sum = new float[2]; if (this.elements == null) throw new InternalError(); int nthreads = ConcurrencyUtils.getNumberOfThreads(); if ((nthreads > 1) && (size >= ConcurrencyUtils.getThreadsBeginN_1D())) { nthreads = Math.min(nthreads, size); Future[] futures = new Future[nthreads]; float[][] results = new float[nthreads][2]; int k = size / nthreads; for (int j = 0; j < nthreads; j++) { final int firstIdx = j * k; final int lastIdx = (j == nthreads - 1) ? size : firstIdx + k; futures[j] = ConcurrencyUtils.submit(new Callable() { public float[] call() throws Exception { float[] sum = new float[2]; int idx = zero + firstIdx * stride; for (int k = firstIdx; k < lastIdx; k++) { sum[0] += elements[idx]; sum[1] += elements[idx + 1]; idx += stride; } return sum; } }); } try { for (int j = 0; j < nthreads; j++) { results[j] = (float[]) futures[j].get(); } sum = results[0]; for (int j = 1; j < nthreads; j++) { sum[0] = sum[0] + results[j][0]; sum[1] = sum[1] + results[j][1]; } } catch (ExecutionException ex) { ex.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } else { int idx = zero; for (int k = 0; k < size; k++) { sum[0] += elements[idx]; sum[1] += elements[idx + 1]; idx += stride; } } return sum; } protected int cardinality(int maxCardinality) { int cardinality = 0; int idx = zero; int i = 0; while (i < size && cardinality < maxCardinality) { if (elements[idx] != 0 || elements[idx + 1] != 0) cardinality++; idx += stride; i++; } return cardinality; } protected boolean haveSharedCellsRaw(FComplexMatrix1D other) { if (other instanceof SelectedDenseFComplexMatrix1D) { SelectedDenseFComplexMatrix1D otherMatrix = (SelectedDenseFComplexMatrix1D) other; return this.elements == otherMatrix.elements; } else if (other instanceof DenseFComplexMatrix1D) { DenseFComplexMatrix1D otherMatrix = (DenseFComplexMatrix1D) other; return this.elements == otherMatrix.elements; } return false; } public long index(int rank) { return zero + rank * stride; } protected FComplexMatrix1D viewSelectionLike(int[] offsets) { return new SelectedDenseFComplexMatrix1D(this.elements, offsets); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy