Package de.torstennahm.integrate.sparse

Source Code of de.torstennahm.integrate.sparse.ProductWeightIntegrator$InternalIntegrator

/*
* Created on Jul 6, 2003
*/
package de.torstennahm.integrate.sparse;

import de.torstennahm.integrate.IntegrationFailedException;
import de.torstennahm.integrate.quadratureformula.Generator;
import de.torstennahm.integrate.quadratureformula.QuadratureFormula;
import de.torstennahm.integrate.sparse.index.Index;
import de.torstennahm.math.Function;
import de.torstennahm.math.IntEntry;

/**
* Integrates a function by using product weights generated from a one-dimensional
* quadrature formula generator, with a depth specified seperately for each dimension.
* <p>
* This class is a helper class for sparse grid integration. It is not part of
* the <code>Integrator</code> hierarchy, as it does not support open-ended
* integration, but only uses a fixed number of points.
* <p>
* This class is thread-safe.
*
* @author Torsten Nahm
*/
public class ProductWeightIntegrator {
  final private Generator generator;
 
  /**
   * Construct the integrator with the specified quadrature formula generator.
   * If the generator is slow, it should be wrapped in a <code>de.torstennahm.integrate.quadratureformula.GeneratorCache</code>
   * before passing it to this class.
   *
   * @param generator quadrature formula generator
   */
  public ProductWeightIntegrator(Generator generator) {
    this.generator = generator;
  }
 
  /**
   * Integrates the function at the specified index by using the tensor product of one-dimensional
   * quadrature formulas. The entry <code>index.getEntry(i)</code> will tell
   * the algorithm to use the quadrature formula returned by
   * <code>getQuadratureFormulaByLevel(index.getEntry(i))</code> for the
   * dimension <code>i</code>. In this way, the index specifies the
   * depth of integration for each dimension.
   *
   * @param index integration index
   * @return integral value
   * @throws IntegrationFailedException if an integration error occurs
   */ 
  public double integrateWithIndex(Function function, Index index) throws IntegrationFailedException {
    QuadratureFormula[] qf = new QuadratureFormula[function.inputDimension()];
   
    for (int i = 0; i < qf.length; i++) {
      int level = index.get(i);
     
      if (level > generator.maxLevel()) {
        throw new IntegrationFailedException("Generator does not support level " + level);
      }
      qf[i] = generator.getByLevel(level);
    }
   
    return new InternalIntegrator(function, qf).value;
  }
 
  public double integrateWithNodes(Function function, int[] nodes) throws IntegrationFailedException {
    QuadratureFormula[] qf = new QuadratureFormula[function.inputDimension()];
   
    for (int i = 0; i < qf.length; i++) {
      if (nodes[i] > generator.maxNodes()) {
        throw new IntegrationFailedException("Generator does not support " + nodes[i] + "nodes");
      }
      qf[i] = generator.getByNodes(nodes[i]);
    }
   
    return new InternalIntegrator(function, qf).value;
  }
 
  private class InternalIntegrator {
    Function function;
    Index index;
    int dimension;
    QuadratureFormula[] quadratureFormulas;
   
    double[] x;
    double value;
     
    InternalIntegrator(Function function, QuadratureFormula[] qf) {
      this.function = function;
      this.quadratureFormulas = qf;
     
      dimension = function.inputDimension();
     
      x = new double[dimension];
     
      value = DoIntegrate(0);
    }
   
    double DoIntegrate(int entryNum) {
      double value;
   
      if (entryNum == dimension) {
        value = function.sEvaluate(x);
      }
      else {
        QuadratureFormula w = quadratureFormulas[entryNum];
     
        value = 0.0;
        int size = w.getSize();
        for (int i = 0; i < size; i++) {
          x[entryNum] = w.getNode(i);
          value += DoIntegrate(entryNum + 1) * w.getWeight(i);
        }
      }
   
      return value;
    }
  }
 
  /**
   * Returns whether integration is possible with the given index.
   *
   * @param index
   * @return <code>true</code> if integration with this index is possible
   */
  public boolean canIntegrate(Index index) {
    int max = generator.maxLevel();
    if (max != -1) {
      for (IntEntry entry : index) {
        if (entry.getValue() > max) {
          return false;
        }
      }
    }
   
    return true;
  }
 
  /**
   * Returns the number of evaluations of the function needed for evaluation
   * of the specified index.
   *
   * @param index integration index
   * @return number of evaluations; <tt>0</tt> is returned if the integration with this index is not possible
   */
  public int neededEvaluations(Index index) {
    int evals = 1;
    int max = generator.maxLevel();
   
    for (IntEntry entry : index) {
      int value = entry.getValue();
      if (max != -1 && value > max) {
        evals = 0;
      } else {
        evals *= generator.getByLevel(value).getSize();
      }
    }
   
    return evals;
  }
 
  public int neededEvaluations(int[] nodes) {
    int evals = 1;
    int max = generator.maxNodes();
   
    for (int num : nodes) {
      if (max != -1 && num > max) {
        evals = 0;
      } else {
        evals *= generator.getByNodes(num).getSize();
      }
    }
   
    return evals;
  }
 
  @Override
  public String toString() {
    return "ProductWeightIntegrator with " + generator;
  }
}
TOP

Related Classes of de.torstennahm.integrate.sparse.ProductWeightIntegrator$InternalIntegrator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.