Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4
  1. #1
    Regular Coder djh101's Avatar
    Join Date
    May 2009
    Location
    California
    Posts
    614
    Thanks
    48
    Thanked 64 Times in 64 Posts

    caret (^) to pow() function

    Having to work with derivatives a lot, I made this nice, simple function for converting a^b form exponents in strings to eval'able pow(a,b) form. Enjoy.

    PHP Code:
    function carToPow($expression){
        
    //array of positions: start of base, position of ^, end of power
        
    $pos = array(null,null,null);
        
    //array of parts: base and power
        
    $parts = array();
        
        for(
    $i=0$i<strlen($expression); $i++){
            
            if(
    $expression[$i] === '^'){
                
    $pos[1] = $i;
                
                
    //scan for base
                
    if($expression[$i-1] === ')'){ //base is a function
                    
    $depth 0;
                    for(
    $j=$i-1$j >= 0$j--){
                        if(
    $expression[$j] === ')'$depth++;
                        if(
    $expression[$j] === '('$depth--;
                        if(
    $depth == 0){
                            
    $pos[0] = $j;
                            
    $parts[0] = substr($expression$j$i-$j);
                            break;
                        }
                    }
                } else if(
    $expression[$i-1] === 'x'){ //base is a variable
                    
    $pos[0] = $i-1;
                    
    $parts[0] = "x";
                } else { 
    //base is a number
                    
    if(preg_match("/\\d*\\.{0,1}\\d+\\^/",$expression,$foo)){
                        
    $pos[0] = $i strlen($foo[0]) + 1;
                        
    $parts[0] = substr($foo[0],0,strlen($foo[0])-1);
                    } else return 
    false;
                }
                
                
    //scan for power
                
    if($expression[$i+1] === '('){ //power is a function
                    
    $depth 0;
                    for(
    $j=$i+1$j strlen($expression); $j++){
                        if(
    $expression[$j] === '('$depth++;
                        if(
    $expression[$j] === ')'$depth--;
                        if(
    $depth == 0){
                            
    $pos[2] = $j;
                            
    $parts[1] = substr($expression$i+1$j-$i);
                            break;
                        }
                    }
                } else if(
    $expression[$i+1] === 'x'){ //base is a variable
                    
    $pos[2] = $i+1;
                    
    $parts[1] = "x";
                } else { 
    //power is a number
                    
    if(preg_match("/\\^\\d*\\.{0,1}\\d+/",$expression,$foo)){
                        
    $pos[2] = $i strlen($foo[0]) - 1;
                        
    $parts[1] = substr($foo[0],1,strlen($foo[0])-1);
                    } else return 
    false;
                }
                
                if(
    $parts[0] == null || $parts[1] == null) return false;
                
    $expression substr($expression,0,$pos[0]).'pow('.$parts[0].','.$parts[1].')'.substr($expression,$pos[2]+1,strlen($expression)-$pos[2]);
                return (
    $expression carToPow($expression)) ? $expression false;
                
            }
            
        }
        return 
    $expression;
        

    Last edited by djh101; 02-28-2012 at 06:27 PM.
    "Yeah science!"
    Online Science Tools

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    I don't know if I'd recommend that the caret be replaced since you'll lose the concept of the xor, but why not just use a regex to match it completely?
    PHP Code:
    $sEquation '452.2 ^ x + 14 - y';

    $sPattern '/([a-z]|\d+(?:\.\d+)?)*\s*\^\s*([a-z]|\d+(?:\.\d+)?)/i';
    $sReplace 'pow($1, $2)';

    $sResult preg_replace($sPattern$sReplace$sEquation);

    print 
    $sResult
    That will give you the same result. Granted without using a stack for this, the behaviour becomes slightly unusual if you provide an unmarked multiplication.

  • #3
    Regular Coder djh101's Avatar
    Join Date
    May 2009
    Location
    California
    Posts
    614
    Thanks
    48
    Thanked 64 Times in 64 Posts
    This is intended for strings of standard math functions, where ^ is used for exponential expressions (and xor is not used at all). Your code works fine for standard a^b expressions, but the stack is needed for converting functions where the base or exponent is a parenthetical expression.
    "Yeah science!"
    Online Science Tools

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Ooh yeah I do see what you mean, never thought about parenthetical expressions for the exponent, and its a mess if you have pow of pow (...of pow...*).
    I know this can be done in regex as well, but I'm afraid that's beyond my skills as a matcher for sure. Stack handling even iterating is probably faster than the pattern would be anyway.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •