Παρασκευή 13 Σεπτεμβρίου 2019

Xonly Function Parser Mononym as Polyonym

package dim.math.func;

import dim.A;
import dim.ext.javax.swing.tree.Dmtn;//DefaultMutableTreeNode
import java.lang.reflect.Constructor;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Vector;


/**
 *
 * @author jimidimi
 */
public class Parser extends Dmtn{
    public static Parser main=new Parser();
 
    public static void main(String[] args) {
        //test1();
        build();
    }
    static void test1(){
        Mononymo m=new Mononymo(8);
        m.xDyn=2.0;
        System.out.println(""+m.f(2));
        m.addDia(new Mononymo(2));
        System.out.println(""+m.f(2));
        m.addDia(new Mononymo(4));
        System.out.println(""+m.f(2));


        System.out.println(""+m);

     
    }
    static void build(){
        String testBrack="5x+(x-3-pe)+pow(x+3,sum(1,2pow(2,x+1),3x+1))";
        testBrack="geom(0,e,44)";
        Parser t=new Parser();
        t.parse(testBrack);
        //new Efr(new Etr(t)).setBounds(0,0,400,700);
     
    }
 
    protected Hashtable<Character, Double> statheres=new Hashtable<>();
    protected String telestes="+-/*%^,";
    protected Vector<String> funks=new Vector<>();
    protected Vector<Constructor> funksCons=new Vector<>();
    public Parser(){
        super("Function Parser version 1 - only x");
     
        statheres.put('p',Math.PI);
        statheres.put('e',Math.E);
        statheres.put('f',(1.0+Math.sqrt(5.0))/2.0);
             
        //0 params
        putClass(Rand.class);

     
        //1 params
        putClass(Abs.class);
        putClass(Sqrt.class);
        putClass(Cbrt.class);
        putClass(Ceil.class);
        putClass(Floor.class);
        putClass(Exp.class);
        putClass(Ln.class);
        putClass(Log.class);
        putClass(Rint.class);
        putClass(Round.class);
        putClass(Signum.class);
        putClass(Rad.class);
        putClass(Deg.class);
        putClass(Sin.class);
        putClass(Cos.class);
        putClass(Tan.class);
        putClass(Asin.class);
        putClass(Acos.class);
        putClass(Atan.class);
        putClass(Sinh.class);
        putClass(Cosh.class);
        putClass(Tanh.class);
         
     
        //2 params
        putClass(Min.class);
        putClass(Max.class);
        putClass(Pow.class);
        putClass(Atanpol.class);
        putClass(Hypot.class);
        putClass(Rem.class);
     
 
     
        //3 params
        putClass(Geom.class);
     
        //multi params
        putClass(Sum.class);
        putClass(Mul.class);
        putClass(Div.class);
     
     
     
    }
    protected synchronized Constructor putClass(Class cl){
        String cln=cl.getSimpleName().toLowerCase();
        Constructor con=null;
        try{
            con=cl.getConstructor(A.azcl);
            funks.add(cln);
            funksCons.add(con);
            //System.out.println(cln+" = "+con);
        }catch(NoSuchMethodException nsme){
            nsme.printStackTrace();
        }
        return con;
    }

    public Mononymo parse(String text){
        Mononymo m=null;
        try{
            Dmtn it,out=parseLevel1(text);
            Object uo;
            Enumeration en=out.depthFirstEnumeration();
            HashSet<Class> hs=new HashSet();
            while(en.hasMoreElements()){
                it=(Dmtn)en.nextElement();
                uo=it.getUserObject();
                if(uo instanceof String){
                    //System.out.println("Mononymizing : "+uo);
                    m=mononimize(it);
                    m.setUserObject(uo);
                    it.setUserObject(m);
                    //System.out.println("-----------");
                }
                hs.add(uo.getClass());
            }
            A.enln(hs.iterator());
         
            //new Efr(new Etr(m).scr()).q(600, 400, 230, 333).qExitOnClose();
            System.out.println("f(-2) = "+m.f(-2));
            System.out.println("f(-1) = "+m.f(-1));
            System.out.println("f(0) = "+m.f(0));
            System.out.println("f(1) = "+m.f(1));
            System.out.println("f(2) = "+m.f(2));
        }catch(Exception e){
            e.printStackTrace();
        }
        return m;
    }
 
    protected Mononymo mononimize(Dmtn level2){
        return mononimize(level2,new Mononymo(1),0,level2.getChildCount());
    }
    protected Mononymo mononimize(Dmtn level2,Mononymo theOut,int i ,int l){
        Mononymo out=theOut;
        if(l>0){
            Dmtn it;
            Object ito;
            char ch,prevch='*';
            double d;
            Func fn;
            if(level2.dmtn(i).getUserObject().equals('-')){
                //System.out.println("-------------");
                out.c=-out.c;
                ++i;
            }
            while(i<l){
                it=level2.dmtn(i);
                ito=it.getUserObject();
                if(ito instanceof Double){
                    d=(Double)ito;
                    if(prevch=='*'){out.c*=d;}
                    else if(prevch=='/'){out.c/=d;}
                    else if(prevch=='%'){out.c%=d;}
                    else if(prevch=='+'){System.err.println("Error +");}
                    else if(prevch=='-'){System.err.println("Error -");}
                }
                else if(ito instanceof Character){
                    ch=(Character)ito;
                    if(ch=='x'){out.xDyn+=1.0;}
                    else if(ch=='*'){prevch=ch;}
                    else if(ch=='/'){prevch=ch;}
                    else if(ch=='%'){prevch=ch;}
                    else if(ch=='+'){prevch='*';
                        Mononymo nm=new Mononymo(1.0);
                        theOut.addSum(nm);
                        out=nm;
                    }
                    else if(ch=='-'){prevch='*';
                        Mononymo nm=new Mononymo(-1.0);
                        theOut.addSum(nm);
                        out=nm;
                    }
                 
                }
                else if(ito instanceof Func){
                   fn=(Func)ito;
                   if(fn.getChildCount()>0){
                       System.err.println("Error on level for "+it);
                   }
                   else{
                       int j=0,k=it.getChildCount();Dmtn fch;Object fo;
                       System.out.println(fn+" ...Functioning "+k+" with ,kommas");
                       int flushedj=0;
                       while(j<k){
                           fch=it.dmtn(j);
                           fo=fch.getUserObject();
                           if(fo.equals(',')){
                               System.out.println("\t"+fo.getClass().getSimpleName()+" = "+fo);
                               fn.add(mononimize(it,new Mononymo(1.0),flushedj,j));
                               flushedj=j+1;
                           }
                           ++j;
                       }
                       fn.add(mononimize(it,new Mononymo(1.0),flushedj,j));
                   }
                    if(prevch=='*'){out.addGin(fn);}
                    else if(prevch=='/'){out.addDia(fn);}
                    else if(prevch=='%'){out.addYpol(fn);}
                    else if(prevch=='+'){out.addSum(fn);}
                    else if(prevch=='-'){System.err.println("Must Mononymo");out.addSum(fn);}
                 
                }
             
                ++i;
            }
        }
     
        return theOut;
    }
 
    protected Dmtn parseLevel1(String text)throws Exception{
        int l=text.length();
        int i=0,j,jl;
        Dmtn out=crad(text);
        char ch;
        String buf;
        Double d;
        while(i<l){
            ch=text.charAt(i);
            if(ch=='('){
                ++i;
                int opened=1;
                buf="";
                while(i<l){
                    ch=text.charAt(i);
                    if(ch=='('){++opened;buf+=ch;}
                    else if(ch==')'){
                        --opened;
                        if(opened<1){break;}
                        else{buf+=ch;}
                    }
                    else{buf+=ch;}
                    ++i;
                }
                //System.out.println("Anadromic parse = "+buf);
                out.add(parseLevel1(buf));
            }
            else if(ch==')'){
                //System.out.println("Closed error?");
                throw new Exception("Brackets closed without opened");
            }
            else if(Character.isLetter(ch)){
                //System.out.println("Initilising constants and ending function names");
                buf=""+ch;
                ++i;
                while(i<l){
                    ch=text.charAt(i);
                    if(Character.isLetter(ch)){buf+=ch;}
                    else{--i;break;}
                    ++i;
                }
                buf=buf.toLowerCase();
                //System.out.println("Hole String = "+buf);
                jl=buf.length();
                Constructor methFound=null;
                if(jl>1){//if more than one char find function from end
                    j=0;
                    jl=funks.size();
                    String meth;
                    while(j<jl){
                        meth=funks.get(j);
                        if(buf.endsWith(meth)){
                            methFound=funksCons.get(j);
                            buf=buf.substring(0,buf.length()-meth.length());
                            break;
                        }
                        ++j;
                    }
                }
                j=0;jl=buf.length();
                //check every char(before function founded or not if it is constant
                while(j<jl){
                    ch=buf.charAt(j);
                    if(ch=='x'){out.crad('x');}
                    else{
                        d=statheres.get(ch);
                        if(d!=null){out.crad(d);}
                        else{throw new IllegalArgumentException("Unknown char = "+ch); }
                    }
                    ++j;
                }
                if(methFound!=null){
                    Func newf=(Func)methFound.newInstance(A.azo);
                    out.crad(newf);
                    //System.out.println("new "+newf.getClass().getSimpleName());
                }
             
            }
            else if(Character.isDigit(ch)||ch=='.'){
                //System.out.println("Initilising numbers");
                buf=""+ch;
                ++i;
                while(i<l){
                    ch=text.charAt(i);
                    if(Character.isDigit(ch)||ch=='.'){buf+=ch;}
                    else{--i;break;}
                    ++i;
                }
                d=Double.parseDouble(buf);
                out.crad(d);//double
            }
            else{
                if(telestes.contains(ch+"")){
                    out.crad(ch);//char
                }
                else{
                    throw new IllegalArgumentException("Unknown char = "+ch);
                }
            }

            ++i;
        }
        //return out;
        return parseLevel2(out);
    }
 
    protected Dmtn parseLevel2(Dmtn out){
        //System.out.println("replace ^ with pow()");
        int l=out.getChildCount();
        Dmtn it;Object uo;
        --l;
        char ch;
        while(l>=0){
            it=out.dmtn(l);
            uo=it.getUserObject();
            if(uo instanceof Character){
                ch=(Character)uo;
                if(l>0&&ch=='^'){
                    //System.out.println("Replacing ^ with pow");
                    Dmtn prev=out.dmtn(l-1);
                    Dmtn aft=out.dmtn(l+1);
                    Dmtn newPow=new Dmtn(new Pow());
                    newPow.add(prev);
                    newPow.add(it);
                    newPow.add(aft);
                    it.setUserObject(',');
                    out.insert(newPow, l-1);
                    --l;
                }
            }
            else if(uo instanceof Func){
                if(it.getChildCount()==0){
                    Dmtn aft=out.dmtn(l+1);
                    if(aft.getUserObject() instanceof String){
                        //System.out.println("Transferring parameters inside");
                        out.remove(l+1);
                        int jl=aft.getChildCount()-1;
                        while(jl>=0){
                            it.insert(aft.dmtn(jl), 0);
                            --jl;
                        }
                    }
                }
            }
            --l;
        }
     
     
        return out;
    }
 
}


////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

public class Mononymo extends Func{

    double c=1.0;
    double xDyn=0.0;

    public Mononymo(String sometext) {
        super();
        setUserObject(sometext);
    }
    public Mononymo(double ac){
        c=ac;
    }
    public Mononymo(double ac,Double axpow){
        c=ac;
        xDyn=axpow;
    }

    @Override
    public Dmtn cr() {
        return new Mononymo("");
    }
    
    

    public String toString(){
        String out="";
        if(c<0.0){out+=c+"";}
        else{out+="+"+c;}
        if(xDyn!=0.0){
            out+="x";
            if(xDyn!=1.0){
                out+="^("+xDyn+")";
            }
        }
        //return getUserObject().toString();
        return out+" @ "+getUserObject();
    }
    public boolean hasX(){
        if(xDyn!=0.0){
            return true;
        }
        return super.hasX();
    } 
    
    
    
    private int gin=0,dia=0,ypol=0,sum=0;
    public int gins(){return gin;}
    public int dias(){return dia-gin;}
    public int ypols(){return ypol-dia;}
    public int sums(){return sum-ypol;}
    public double f(double x){
        double out=c;
        out*=Math.pow(x, xDyn);
        int i=0;
        while(i<gin){
            out*=func(i).f(x);
            ++i;
        }
        while(i<dia){
            out/=func(i).f(x);
            ++i;
        }
        while(i<ypol){
            out%=func(i).f(x);
            ++i;
        }
        while(i<sum){
            out+=func(i).f(x);
            ++i;
        }
        return out;
    }
    
    public void addGin(Func f){
        insert(f, gin);
        gin++;
        dia++;
        ypol++;
        sum++;
    }
    public void addDia(Func f){
        insert(f, dia);
        dia++;
        ypol++;
        sum++;
    }
    public void addYpol(Func f){
        insert(f, ypol);
        ypol++;
        sum++;
    }
    public void addSum(Func f){
        add(f);
        ++sum;
    }

}








class Func extends Dmtn{
    public Func(){}
    public String toString(){
        return getClass().getSimpleName();
    }
    public double f(double x){
        return x;
    }
    public Func func(int index){
        return (Func)getChildAt(index);
    }
    public boolean hasX(){
        int l=getChildCount();
        if(l>0){
            int i=0;
            while(i<l){
                if(func(i).hasX()){return true;}
                ++i;
            }
        }
        return false;
    } 

}
class Pow extends Func{
    public Pow() {}
    public double f(double x){
        return Math.pow(func(0).f(x),func(1).f(x));
    }
}
class Min extends Func{
    public Min() {}
    public double f(double x){
        return Math.min(func(0).f(x),func(1).f(x));
    }
}
class Max extends Func{
    public Max() {}
    public double f(double x){
        return Math.max(func(0).f(x),func(1).f(x));
    }
}
class Abs extends Func{
    public Abs() {}
    public double f(double x){
        return Math.abs(func(0).f(x));
    }
}
class Rad extends Func{
    public Rad() {}
    public double f(double x){
        return Math.toRadians(func(0).f(x));
    }
}
class Deg extends Func{
    public Deg() {}
    public double f(double x){
        return Math.toDegrees(func(0).f(x));
    }
}
class Sin extends Func{
    public Sin() {}
    public double f(double x){
        return Math.sin(func(0).f(x));
    }
}
class Asin extends Func{
    public Asin() {}
    public double f(double x){
        return Math.asin(func(0).f(x));
    }
}
class Sinh extends Func{
    public Sinh() {}
    public double f(double x){
        return Math.sinh(func(0).f(x));
    }
}
class Cos extends Func{
    public Cos() {}
    public double f(double x){
        return Math.cos(func(0).f(x));
    }
}
class Acos extends Func{
    public Acos() {}
    public double f(double x){
        return Math.acos(func(0).f(x));
    }
}
class Cosh extends Func{
    public Cosh() {}
    public double f(double x){
        return Math.cosh(func(0).f(x));
    }
}
class Tan extends Func{
    public Tan() {}
    public double f(double x){
        return Math.tan(func(0).f(x));
    }
}
class Atan extends Func{
    public Atan() {}
    public double f(double x){
        return Math.atan(func(0).f(x));
    }
}
class Tanh extends Func{
    public Tanh() {}
    public double f(double x){
        return Math.tanh(func(0).f(x));
    }
}
class Atanpol extends Func{
    public Atanpol() {}
    public double f(double x){
        return Math.atan2(func(0).f(x),func(1).f(x));
    }
}


class Sqrt extends Func{
    public Sqrt() {}
    public double f(double x){
        return Math.sqrt(func(0).f(x));
    }
}
class Cbrt extends Func{
    public Cbrt() {}
    public double f(double x){
        return Math.cbrt(func(0).f(x));
    }
}
class Ceil extends Func{
    public Ceil() {}
    public double f(double x){
        return Math.ceil(func(0).f(x));
    }
}
class Floor extends Func{
    public Floor() {}
    public double f(double x){
        return Math.floor(func(0).f(x));
    }
}
class Rem extends Func{
    public Rem() {}
    public double f(double x){
        return Math.IEEEremainder(func(0).f(x),func(1).f(x));
    }
}
class Exp extends Func{
    public Exp() {}
    public double f(double x){
        return Math.exp(func(0).f(x));
    }
}
class Hypot extends Func{
    public Hypot() {}
    public double f(double x){
        return Math.hypot(func(0).f(x),func(1).f(x));
    }
}

class Ln extends Func{
    public Ln() {}
    public double f(double x){
        return Math.log(func(0).f(x));
    }
}
class Log extends Func{
    public Log() {}
    public double f(double x){
        return Math.log10(func(0).f(x));
    }
}
class Rand extends Func{
    public Rand() {}
    public double f(double x){
        return Math.random();
    }
}
class Rint extends Func{
    public Rint() {}
    public double f(double x){
        return Math.rint(func(0).f(x));
    }
}
class Round extends Func{
    public Round() {}
    public double f(double x){
        return Math.round(func(0).f(x));
    }
}
class Signum extends Func{
    public Signum() {}
    public double f(double x){
        return Math.signum(func(0).f(x));
    }
}

class Sum extends Func{
    public Sum() {}
    public double f(double x){
        int l=getChildCount();
        double out=0.0;
        if(l>0){
            int i=0;
            Func it=func(i);
            out=it.f(x);
            ++i;
            while(i<l){
                out+=func(i).f(x);
                ++i;
            }
        }
        return out;
    }
}
class Mul extends Func{
    public Mul() {}
    public double f(double x){
        int l=getChildCount();
        double out=0.0;
        if(l>0){
            int i=0;
            Func it=func(i);
            out=it.f(x);
            ++i;
            while(i<l){
                out*=func(i).f(x);
                ++i;
            }
        }
        return out;
    }
}
class Div extends Func{
    public Div() {}
    public double f(double x){
        int l=getChildCount();
        double out=0.0;
        if(l>0){
            int i=0;
            Func it=func(i);
            out=it.f(x);
            ++i;
            while(i<l){
                out/=func(i).f(x);
                ++i;
            }
        }
        return out;
    }
}
class Poly extends Func{
    public Poly() {}
    public double f(double x){
        int l=getChildCount();
        double out=0.0;
        if(l>0){
            int i=0;
            Func it=func(i);
            out=it.f(x);
            ++i;
            while(i<l){
                out+=Math.pow(func(i).f(x),i+1);
                ++i;
            }
        }
        return out;
    }
}
class Geom extends Func{
    public Geom() {}
    public double f(double x){
        int l=getChildCount();
        double out=0.0;
        if(l>0){
            int i=0;
            double startFrom=func(i).f(x);
            double lamda=0.5;
            double times=10;
            
            ++i;
            if(i<l){
                lamda=func(i).f(x);
            }
            ++i;
            if(i<l){
                times=func(i).f(x);
            }
            
            
            out=startFrom;
            
            i=0;
            while(i<times){
                startFrom*=lamda;
                out+=startFrom;
                ++i;
            }
        }
        return out;
    }
}


Δεν υπάρχουν σχόλια: