String manipulation of type String substitution in mathematical expression

1

1

Imagine something like

exp(49/200)+(x-49/200)

I want to pass as argument of the function "roundn" whatever operation that is not an addtion or a subtraction So my expresion became

roundn(exp(roundn(49/200,n)),n)+(x - roundn(49/200,n)

Well the expression I want to manipulate is this:

exp(49/200)+exp(49/200)*(x-49/200)+1/2*exp(49/200)*(x-49/200)^2+1/6*exp(49/200)*(x-       49/200)^3+1/24*exp(49/200)*(x-49/200)^4+1/120*exp(49/200)*(x-49/200)^5+1/720*exp(49/200)*(x-49/200)^6+1/5040*exp(49/200)*(x-49/200)^7+1/40320*exp(49/200)*(x-49/200)^8+1/362880*exp(49/200)*(x-49/200)^9+1/3628800*exp(49/200)*(x-49/200)^10+1/39916800*exp(49/200)*(x-49/200)^11

I´m looking for a method (That include whatever program) not based in language programming, as much batch or somithing like that...

Peterstone

Posted 2010-11-22T19:48:44.193

Reputation: 419

Answers

2

Try this:

ro='roundn('    # roundn open
rc=',n)'        # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"

which should give you:

roundn(exp(roundn(49/200,n)),n)+(x-roundn(49/200,n))

Your longer expression should result in:

roundn(exp(roundn(49/200,n)),n)+roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))+roundn(1/2,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^2+roundn(1/6,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^3+roundn(1/24,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^4+roundn(1/120,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^5+roundn(1/720,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^6+roundn(1/5040,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^7+roundn(1/40320,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^8+roundn(1/362880,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^9+roundn(1/3628800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^10+roundn(1/39916800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n) ^11

Explanation

  • /exp\([^)]*\K\)/)$rc/g - close exp(), add roundn close
    • for strings that start with "exp(" and end with ")"
    • \K makes the "exp(" a zero-width match so only the closing paren is replaced
  • s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g - strings of digits with mult and div, surround with roundn open and roundn close
    • strings of digits that don't start with "^" but may contain "/" or "*"
    • must be two or more total characters - there's probably a better way to do this
    • carat is negative look-behind (zero-width) so it's not included when the replacement is made
  • s/exp\([^)]*/$ro\$&/g - open exp(), add roundn open
    • before "exp(" followed by zero or more characters that are not ")", add roundn open
  • $ro, $rc and $fun are shell variables
    • wrapping the Perl script in double quotes allows these variables to be expanded
  • $& contains the entire match except for the zero-width portions
    • escaping it is probably not necessary, but I did it just in case - to keep from confusing the shell

It wouldn't be too hard to make this work if there are more than one function. However, it will probably completely fall apart if they are nested.

Edit:

Here is a Perl script version:

$ro = "roundn(";
$rc = ",n)";
$fun = "exp\\(";
while (<>) {
    s/$fun[^)]*\K\)/)$rc/g;
    s/(?<!\^)[0-9\/*]+[0-9]/$ro$&$rc/g;
    s/$fun[^)]*/$ro$&/g;
    print
}

Run it like this:

perl script.pl < data.txt

Paused until further notice.

Posted 2010-11-22T19:48:44.193

Reputation: 86 075

Does anyone know a solution for this question based on batch (windows shell)? – Peterstone – 2010-11-23T09:11:04.103

@Dennis: freak! :) – akira – 2010-11-23T14:37:04.537

@Peterstone: Perl is available for Windows. The Windows batch language is not capable of this and I doubt that Powershell is by itself. You could probably do it in Python which is also available for Windows. @akira: Thanks! – Paused until further notice. – 2010-11-23T15:19:00.500

@Dennis: Well, I suppose I can download the strawberry perl... – Peterstone – 2010-11-23T17:24:55.410

@Dennis: Do you think I could do it with strawberry perl? – Peterstone – 2010-11-23T17:25:30.760

@Peterstone: Yes. – Paused until further notice. – 2010-11-23T17:40:03.187

@Peterstone: Try the Perl script I added. – Paused until further notice. – 2010-11-23T18:27:09.760

0

Well, I´m trying to execute your code... I make a small program (practicalcase1.pl) with the first paragraph of code you wrote:

ro='roundn('    # roundn open
rc=',n)'        # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"

But I recive some messages on the cmd of windows:

Semicolon seems to be missing at practicalcase1.pl line 1
Semicolon seems to be missing at practicalcase1.pl line 2
Semicolon seems to be missing at practicalcase1.pl line 3
Semicolon seems to be missing at practicalcase1.pl line 4
String found where operator expected at practicalcase1.pl line 5, near "echo "$expression""
(Do you need to predeclare echo?)
String found where operator expected at practicalcase1.pl line 6, near "pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g""
(Do you need to predeclare pe?)
Can´t modify constant item in scalar assigment at practicalcase1.pl line 2, near "rc"
syntax error at practicalcase1.pl line 2, near "rc"
Execution of practicalcase1.pl aborted due to compilation errors.

What could I do with the errors of type "semicolon seems to..."? What it´s supossed I have to do with the error "String found where operator ..."? What about "Can´t modify constant item in scalar..."? What about "syntax error at practicalcase1.pl line2..."

Thank you so much!

Peterstone

Posted 2010-11-22T19:48:44.193

Reputation: 419

The code in my answer is written as a (Unix) shell script rather than a Perl script. To use it in Windows it might be easier to convert it to a Perl script. I will update my answer as soon as possible. – Paused until further notice. – 2010-11-23T17:44:39.547