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 (Abbot) 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..