簡體   English   中英

Java - 創建一個返回偏導數的方法

[英]Java - Creating a method that returns the partial derivative

我需要創建一個方法,當傳遞要區分 w 的 var 時,該方法必須以項的形式返回 function 的偏導數。 這是我的 class 方法是區分:

package poly;

import java.util.ArrayList;
import java.util.TreeSet;

import util.Vector;



/** Implements an individual term in a polynomial.  If 5x^2 + 3xy is a polynomial,
 *  it has two terms 5x^2 and 2xy, each of which would be represented by a different
 *  instance of this class.
 * 
 * @author ssanner@mie.utoronto.ca
 *
 */
public class Term {

    // For term 2.1*x^4*y*z^2, the data members would take values as follows:
    public double _coef; // = 2.1
    public ArrayList<String>  _vars; // = ["x", "y", "z"]
    public ArrayList<Integer> _pows; // = [4, 1, 2]

    /** This constructor has been implemented for you.
     * 
     * @param coef -- sets the _coef member
     */
    public Term(double coef) {
        _coef = coef;
        _vars = new ArrayList<String>();
        _pows = new ArrayList<Integer>();
    }

    /** This constructor has been implemented for you -- it parses a term 
     *  representation from a String into the format required by this class.
     *  You need two understand the following code.
     * 
     * @param s -- String to parse
     * @throws PolyException if s is malformed
     */
    public Term(String s) throws PolyException {

        if (s == null || s.trim().equals(""))
            throw new PolyException("Empty Term, cannot read");

        // Initialize this term
        _coef = 1.0d; // Will multiply any constants by this
        _vars = new ArrayList<String>();
        _pows = new ArrayList<Integer>();

        // You need to understand all lines of the following code
        String[] factors = s.split("\\*");
        for (String factor : factors) {
            factor = factor.trim(); // Get rid of leading and trailing whitespace
            try {
                // If successful, multiplies in a constant (multiple constants in a product allowed)
                _coef *= Double.parseDouble(factor);                    
            } catch (NumberFormatException e) {
                // If not a coefficient, must be a factor "<var>^<pow>"
                // Must be a variable to a power -- parse the factor and add to list
                int pow = 1; // If no power, defaults to 1
                String[] var_pow = factor.split("\\^");
                String var = var_pow[0];
                if (var_pow.length == 2) {
                    try { // Second part must be exponent
                        pow = Integer.parseInt(var_pow[1]);
                    } catch (NumberFormatException f) {
                        throw new PolyException("ERROR: could not parse " + factor);
                    }
                } else if (var_pow.length > 2) 
                    throw new PolyException("ERROR: could not parse " + factor);

                // Successfully parsed variable and power, add to list
                if (_vars.contains(var))
                    throw new PolyException("ERROR: " + var + " appears twice in " + s);
                _vars.add(var);
                _pows.add(pow);
            }
        }
    }

    /** Produce a re-parseable representation of this Term as a String.  This
     *  has been done for you.
     * 
     */
    public String toString() {
        // Using "+" to append Strings involves a lot of String copies since Strings are 
        // immutable.  StringBuilder is much more efficient for append.
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%01.3f", _coef));
        for (int i = 0; i < _vars.size(); i++) {
            String var = _vars.get(i);
            int pow = _pows.get(i);
            sb.append("*" + var + (pow == 1 ? "" : "^" + pow));
        }
        return sb.toString();
    }

    /** Returns all of the variables used in this Term as a sorted set (TreeSet).
     *  This has been implemented for you, but you need to understand how it works
     *  since you'll write a similar method in Polynomial that uses this method.
     * 
     * @return
     */
    public TreeSet<String> getAllVars() {
        // TreeSets are like HashSets but sorted alphabetically (lookup and insertion are
        // a little less efficient than HashSets, but this won't matter for our sizes).
        return new TreeSet<String>(_vars);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // TODO: Your methods here!  You should add some helper methods that facilitate
    //       the implementation of the methods below.
    ///////////////////////////////////////////////////////////////////////////////

    /** If Term defines a function f(x,y) = 2xy^2 and assignments is { x=2.0 y=3.0 } 
     *  then this method returns 36.0, which is the evaluation of f(2.0,3.0). 
     * 
     * @param assignments
     * @return
     * @throws PolyException
         * 
         * 
     */

        public double coef(){
            return _coef;
        }
        public Double var(int i){
            return Double.parseDouble(_vars.get(i));
        }
        public ArrayList power(){
            return _pows;
        }

    public double evaluate(Vector assignments) throws PolyException {

            double evaluated = 0;
            double sum = 0;

            for(int i = 0; i < _vars.size(); i++){
             sum +=  Math.pow(var(i), _pows.get(i));   
            }

            evaluated *= sum;
            return evaluated;

    }

    /** If Term defines a function f(.) then this method returns the **symbolic**
     *  partial derivative (which you can verify from calculus is still a Term):
     *  
     *    partial f(1.0,2.0) / partial var.
     * 
     *  Specifically, if Term defines a function f(x,y) = 2xy^2 and var = "x"
     *  then this method returns a **new** Term 2y^2 and if var = "y" then it
     *  instead returns a **new** Term 4xy.
     * 
     * @param var
     * @return partial derivative of this w.r.t. var as a new Term
     */
    public Term differentiate(String var) {

        // TODO: Should not return null!                  


        return null;
    }

}

我不確定如何調用 distinct 方法,但是可以像下面這樣來區分相對簡單的 function 的方法示例...

請注意,此方法可以使用一些微調(它返回一個字符串而不是 Term 值)並且它不考慮日志/觸發函數等,但希望這是一個有用的開始。

public static void main(String args[]) {
    String differentiated = differentiate("32x^2y^3", "x");
    System.out.println(differentiated);
}


public static String differentiate(String function, String var) {

    StringBuilder partialDerivative = new StringBuilder();
    int indexOfVar = function.indexOf(var);
    boolean coefficient = false;
    String coefficientValue;
    double coefficientAmount = 1;
    StringBuilder powerValue = new StringBuilder();
    StringBuilder variable = new StringBuilder();
    double powerAmount;
    StringBuilder otherVariables = new StringBuilder();

    //ascertains whether a coefficient is present
    int k = 0;
    while (Character.isDigit(function.charAt(k))) {
        coefficient = true;
        if (k == 0) {
            coefficientValue = Character.toString(function.charAt(k));
        } else {
            coefficientValue = function.substring(0, k+1);
        }
        coefficientAmount = Double.parseDouble(coefficientValue);
        k++;
    }

    //checks for other variables that may also have polynomials
    for (int i = 0; i <= function.length() - 1; i++) {
        if (Character.isLetter(function.charAt(i)) && function.charAt(i) != var.charAt(0)) {
            otherVariables.append(function.charAt(i));
            if (i < function.length() - 1) {
                if (function.charAt(i + 1) == '^') {
                    findPolynomial(function, i, otherVariables);
                }
            }
        }
    }


    //works out if the var value has a polynomial and therefore times the coefficient by it and reduces it by one
    if (function.charAt(indexOfVar + 1) == '^') {
        findPolynomial(function, indexOfVar, powerValue);
        powerAmount = Double.parseDouble(powerValue.toString().substring(1));
        coefficientAmount *= powerAmount;
        powerAmount -= 1;
        powerValue.replace(1,powerValue.length(),Double.toString(powerAmount));
        if(powerAmount != 1) {
            variable.append(var).append(powerValue);
        } else {
            variable.append(var);
        }
    }

    //include method for ln() or exponential functions

    //include method for trig functions (sin() cos() etc)

    if (coefficient) {
        partialDerivative.append(coefficientAmount).append(otherVariables).append(variable);
    } else {
        partialDerivative.append(otherVariables).append(variable);
    }

    return partialDerivative.toString();
}

private static void findPolynomial(String function, int indexOfVar, StringBuilder powerValue) {
    powerValue.append(function.charAt(indexOfVar + 1));
    int j = indexOfVar + 2;
    while (Character.isDigit(function.charAt(j))) {
        powerValue.append(function.charAt(j));
        if (j == function.length() - 1) {
            break;
        } else {
            j++;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM