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

com.enterprisemath.math.fa.IntegrationUtils Maven / Gradle / Ivy

The newest version!
package com.enterprisemath.math.fa;

import com.enterprisemath.math.algebra.Hypercube;
import com.enterprisemath.math.algebra.Interval;
import com.enterprisemath.math.algebra.Vector;
import com.enterprisemath.utils.ValidationUtils;

/**
 * Class with utility method for integration calculation.
 * 
 * @author radek.hecl
 *
 */
public final class IntegrationUtils {

    /**
     * To prevent construction.
     */
    private IntegrationUtils() {
    }

    /**
     * Integrates function over the specified interval. Returns the value.
     * Rectangle / midpoint method is used for calculation.
     * 
     * @param fnc function to be integrated
     * @param interval interval
     * @param step maximum allowed step, must be positive (smaller step might be used)
     * @return result of the integration
     */
    public static double integrateOnInterval(Function fnc, Interval interval, double step) {
        ValidationUtils.guardPositiveDouble(step, "step must be positive");
        int numSteps = (int) (interval.getSize() / step) + 1;
        step = interval.getSize() / numSteps;
        double min = interval.getMin();
        double max = interval.getMax();
        double res = 0;
        for (double pos = min + step / 2; pos < max; pos += step) {
            res += fnc.getValue(pos) * step;
        }
        return res;
    }

    /**
     * Integrates function over the specified hypercube. Returns the value.
     * Rectangle / midpoint method is used for calculation.
     * 
     * @param fnc function to be integrated
     * @param hypercube hypercube
     * @param step maximum allowed step, must be positive (smaller step might be used)
     * @return result of the integration
     */
    public static double integrateOnHypercube(Function fnc, Hypercube hypercube, double step) {
        ValidationUtils.guardPositiveDouble(step, "step must be positive");
        ValidationUtils.guardPositiveInt(hypercube.getDimension(), "hypercube must have positive dimension");
        if (hypercube.getDimension() == 1) {
            int numStepsX = (int) (hypercube.getSize().getComponent(0) / step) + 1;
            double stepX = hypercube.getSize().getComponent(0) / numStepsX;
            double minX = hypercube.getMin().getComponent(0);
            double maxX = hypercube.getMax().getComponent(0);
            double res = 0;
            double vol = stepX;
            for (double posX = minX + stepX / 2; posX < maxX; posX += stepX) {
                res += fnc.getValue(Vector.create(posX)) * vol;
            }
            return res;            
        }
        else if (hypercube.getDimension() == 2) {
            // x
            int numStepsX = (int) (hypercube.getSize().getComponent(0) / step) + 1;
            double stepX = hypercube.getSize().getComponent(0) / numStepsX;
            double minX = hypercube.getMin().getComponent(0);
            double maxX = hypercube.getMax().getComponent(0);
            // y
            int numStepsY = (int) (hypercube.getSize().getComponent(1) / step) + 1;
            double stepY = hypercube.getSize().getComponent(1) / numStepsY;
            double minY = hypercube.getMin().getComponent(1);
            double maxY = hypercube.getMax().getComponent(1);
            
            double res = 0;
            double vol = stepX * stepY;
            for (double posX = minX + stepX / 2; posX < maxX; posX += stepX) {
                for (double posY = minY + stepY / 2; posY < maxY; posY += stepY) {
                    res += fnc.getValue(Vector.create(posX, posY)) * vol;
                }
            }
            return res;            
        }
        else if (hypercube.getDimension() == 3) {
            // x
            int numStepsX = (int) (hypercube.getSize().getComponent(0) / step) + 1;
            double stepX = hypercube.getSize().getComponent(0) / numStepsX;
            double minX = hypercube.getMin().getComponent(0);
            double maxX = hypercube.getMax().getComponent(0);
            // y
            int numStepsY = (int) (hypercube.getSize().getComponent(1) / step) + 1;
            double stepY = hypercube.getSize().getComponent(1) / numStepsY;
            double minY = hypercube.getMin().getComponent(1);
            double maxY = hypercube.getMax().getComponent(1);
            // z
            int numStepsZ = (int) (hypercube.getSize().getComponent(2) / step) + 1;
            double stepZ = hypercube.getSize().getComponent(2) / numStepsZ;
            double minZ = hypercube.getMin().getComponent(2);
            double maxZ = hypercube.getMax().getComponent(2);
            
            double res = 0;
            double vol = stepX * stepY * stepZ;
            for (double posX = minX + stepX / 2; posX < maxX; posX += stepX) {
                for (double posY = minY + stepY / 2; posY < maxY; posY += stepY) {
                    for (double posZ = minZ + stepZ / 2; posZ < maxZ; posZ += stepZ) {
                        res += fnc.getValue(Vector.create(posX, posY, posZ)) * vol;
                    }
                }
            }
            return res;            
        }
        else {
            throw new RuntimeException("TODO - implement me if you need");
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy