Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Solve for 'x' in series

by sbae (Initiate)
on Mar 17, 2018 at 01:49 UTC ( [id://1211093]=perlquestion: print w/replies, xml ) Need Help??

sbae has asked for the wisdom of the Perl Monks concerning the following question:

Hello Perl Monks,

I am trying to program series equation in Perl and solve for the 'x' at the end.

my equation is

$c = 1 or 0; - different value(0 or 1) for each for loop

$q is given value - different value each for loop though

for ($i=1; $i<1000; i++) { $sum_equ ={(1-$c[$i])(1-2*$q[$i])}/(-2*$q[$i]*$x +$x +$q[$i]) + +{$c[$i]*(2*$q[$i] -1)}/(2*$q[$i]*$x-$x+1) }

$c values determines which part of valued to be added.

I am hoping '$sum_equ' contains sum of all equations and set the final equations as zero, then solve for the $x value at the end.

for example...

I have 1000 iterations to to be begin with $sum_equ = 0;

when i=0; $sum_equ = (1 - 2*10)/(-2*10*$x +$x +10); when i=1; $sum_equ = (1 - 2*10)/(-2*10*$x +$x +10) +(2*5 -1)/(2* +5*$x-$x+1); ..... when i=999; $sum_equ = (1 - 2*10)/(-2*10*$x +$x +10) +(2*5 -1)/( +2*5*$x-$x+1)+ ....... + (2*22 -1)/(2*22*$x-$x+1);

then $sum_equ = 0

Solve for $x value

pseudo code would be... I am stuck at what functions to use or how to implement it...

for ($i=1;$i<1000;$i++) { if ($c==1) { $sum_equ = $sum_equ + (1 - 2*$q[$i]/(-2*$q[$i] +*$x +$x +$q[$i] ); } elsif ($c ==0) { $sum_equ = $sum_equ + (2*$q[$i] -1)/(2*$q[$i]* +$x-$x+1); } # End of if } #end of for

I would greatly appreciate any comments or opinion.

Thank you so much.

2018-03-22 Athanasius Added code tags and removed paragraph tags from within code

Replies are listed 'Best First'.
Re: Solve for 'x' in series
by choroba (Cardinal) on Mar 17, 2018 at 07:52 UTC
    I don't understand what your equation is. How is q=22 related to i=999? You seem not to use $i at all in the formulas, is that OK? Or do you mean @q by $q and $q[$i] by "different value each for loop though"?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Sorry for the confusion. you are right. I meant $q$i by "different value each for loop though". I have edited my node based on your comment. - I was wondering how I could accumulate all the equations by for loop and then solve for the x value at the end - assuming the final equation is equal to zero. Thanks a lot.
Re: Solve for 'x' in series
by bliako (Monsignor) on Mar 17, 2018 at 19:15 UTC

    What I understand is that your coefficients are numerical but your $x (as you wrote it) is just a symbol in an equation and not a variable in a computer program.

    So, provided I understood correctly, what you are looking for is a package capable of symbolic calculations.

    There is one in perl already:

    use Math::Calculus::NewtonRaphson; use strict; use warnings; my $exp = Math::Calculus::NewtonRaphson->new(); $exp->addVariable('x'); # our variable in the equations $exp->setExpression('x+3*x-x^2'); if( $exp->getError() ){ print "got error, ".$exp->getError()."\n"; exi +t(1) } my $result = $exp->newtonRaphson('x', 0); print "result: ".$result."\n";

    Which gets fatal errors unfortunately.

    Do you have any more options?

    Yes you do. At least two.

    1) Use perl to produce the sum equation in symbolic form (e.g. 1/(10*x)) and then use the symbolic solver in package R.

    library(rSymPy) x <- Var("x") sympy("solve(3+3*x-x*x, x)")

    The answer in this simple example is:

    [1] "[3/2 - 21**(1/2)/2, 3/2 + 21**(1/2)/2]"

    But you still need perl in order to produce the final equation as a string containing numbers and the letter 'x' (which is your symbolic variable you want to solve for). In the following code I have omitted the $c==0 or $c==1 logic.

    use strict; use warnings; my $i; my @q = map { rand() } (1..1000); # your 1000 'q' coefficients as just + random numbers here my @c = map { rand() } (1..1000); # your 1000 'c' coefficients as just + random numbers here my ($a1, $a2, $a3); my $sum_equ = ""; for ($i=1; $i<1000; $i++) { $a1 = (1-$c[$i])*(1-2*$q[$i]); $a2 = -2*$q[$i]; $a3 = $c[$i]*(2*$q[$i] -1); # concatenate the equation of this time with the total equation: $sum_equ = $sum_equ . "($a1/($a2 * x + x + $q[$i]) + $a3/(2*q[$i +]*x-x+1)) + "; } $sum_equ =~ s/\+\s*$//; # remove last + print "library(rSymPy)\n\ x <- Var('x')\n\ sympy('solve($sum_equ, x)')\n ";

    Save the above code to a file called 'equ.pl' and then from the command-line do:

    perl equ.pl | R

    It will probably give you the solution crash your computer (because the equation is huge).

    2) Your second option (and your only option if your computer crashed in option #1) requires a bit more thinking because you need to handcraft your equations before concatenating in order to do some simplifications of the form 3*x + x => 4*x. How are you going to achieve that? You need to start from your basis equations and accumulate the coefficients of 'x' 'x^2' (if any) in a single variable etc..

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1211093]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2024-04-19 04:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found