How do I get imaginary numbers without using cmath when calculating the quadratic equation? - python-2.7

I'm currently having trouble understanding how to make imaginary numbers appear when I'm doing the quadratic equation. My assignment is to make the quadratic equation, and get imaginary numbers but I'm having an extremely difficult time getting there.
any help you can offer would be great!
Here is the code i currently have:
import math
print "Hello, please insert 3 numbers to insert into the quadratic equation."
a = input("Please enter the first value: ")
b = input("Please enter the second value: ")
c = input("Please enter the third value: ")
rootValue = b**2 - 4*a*c
if rootValue < 0:
print (-b-(rootValue)**(.5)) / (2 * a)
if rootValue > 0:
print ((-b + (rootValue)**(1/2)) /(2 * a))
if rootValue == 0:
print -b/(2*a)
please help!!! i'm so stuck right now.
I think you have to do something with the problem if rootValue < 0; but I'm not sure how to do that.
I'm also not allowed to use 'import cmath', I'm supposed to make it so that you can just do this this way.

There are a couple of problems with your code besides how to represent complex numbers. Remember that if rootValue <> 0, there are ALWAY TWO roots:
(-b +/- sqrt(rootValue)/ 2a
It doesn't matter if the rootValue is positive or negative, there's still two roots. You are branching and only providing one of the two roots in each case. No need for the first two if statements
To make rootValue complex, so that you can have complex result when you take the square root, either set it equal to complex(b2 - 4*a*c, 0) or to (b2 - 4*a*c, 0) + 0j.
You want to raise things to the 0.5 power for each of the two roots, NOT the (1/2) power, as you've done in one statement
For completeness, you may want to deal with the a = 0 case.
If you still have problems, let us know.

Related

Removing Cyclotomic Factors from a Polynomial - Pari

I want to take some polynomial f and remove all of it's cyclotomic factors, and then look at the resulting polynomial (say g). I'm aware of polcyclofactors and the current code I have tried is:
c(f)=polcyclofactors(f)
p(f)=prod(i=1,#c(f),c(f)[i])
g(f)=f/p(f)
The issue I have is that polcyclofactors doesn't take into account multiplicity of the cyclotomic factors. For example:
f=3*x^4 + 8*x^3 + 6*x^2 - 1
g(f)
= 3*x^3 + 5*x^2 + x - 1
But
factor(f)
=
[ x + 1 3]
[3*x - 1 1]
Is there any way to be able to nicely include multiple cyclotomic factors of f to divide by? Or will I have to look at factorising f and try and removing cyclotomic factors that way?
The following two suggestions are based on repeating the divisions until no more can be done (they are both very similar).
Suggestion 1:
r(f)={my(c); while(c=polcyclofactors(f); #c, f=f/vecprod(c)); f}
Suggestion 2:
r(f)={my(g=vecprod(polcyclofactors(f))); while(poldegree(g), f=f/g; g=gcd(f,g)); f}
Another suggestion without a loop:
r(f)={my(g=vecprod(polcyclofactors(f))); numerator(f/g^(poldegree(f)))}
Now a version that is probably superior: For each factor valuation can be used to get the required power.
r(f)={f/vecprod([t^valuation(f,t) | t<-polcyclofactors(f)])}

finding the big oh estimate of the a simple print function

while (num > 1)
{
cout << "num is now " << num << endl;
cout << "hello // \n";
num /= 2;
}
I am trying to give the big O estimate for the print statements.
The user gets to input num. I tried a few inputs and am starting to see a pattern.
1 gives 0 print.
2-3 gives 1 print.
4-7 gives 2 prints.
8-15 gives 3 prints.
16-31 gives 4 prints.
let p = the number of prints. I see that the range of numbers giving you a certain amount of prints is 2^p.
So is the big O estimate 2^p ?
You are definitely thinking in the right direction and what is more important - you are approaching the problem in the correct manner. Still your final conclusion is a bit off the target. Try to use 2p for the values you've computed and you will see that the number of prints is not 2p, but rather the inverse of this function.
It's O(log N). The reason is that your halving the range with each iteration. If you're familar with binary search then your loop if doing something similar.
You've correctly observed the 2^p pattern. The inverse of this is log base-2 (rather than log base-10). When people mention log in big-O notation they typically mean the base-2 version.
just use the master theorem.
Link here
b = 2 f(n) = 1 a = 1.

Solving a linear equation in one variable

What would be the most efficient algorithm to solve a linear equation in one variable given as a string input to a function? For example, for input string:
"x + 9 – 2 - 4 + x = – x + 5 – 1 + 3 – x"
The output should be 1.
I am considering using a stack and pushing each string token onto it as I encounter spaces in the string. If the input was in polish notation then it would have been easier to pop numbers off the stack to get to a result, but I am not sure what approach to take here.
It is an interview question.
Solving the linear equation is (I hope) extremely easy for you once you've worked out the coefficients a and b in the equation a * x + b = 0.
So, the difficult part of the problem is parsing the expression and "evaluating" it to find the coefficients. Your example expression is extremely simple, it uses only the operators unary -, binary -, binary +. And =, which you could handle specially.
It is not clear from the question whether the solution should also handle expressions involving binary * and /, or parentheses. I'm wondering whether the interview question is intended:
to make you write some simple code, or
to make you ask what the real scope of the problem is before you write anything.
Both are important skills :-)
It could even be that the question is intended:
to separate those with lots of experience writing parsers (who will solve it as fast as they can write/type) from those with none (who might struggle to solve it at all within a few minutes, at least without some hints).
Anyway, to allow for future more complicated requirements, there are two common approaches to parsing arithmetic expressions: recursive descent or Dijkstra's shunting-yard algorithm. You can look these up, and if you only need the simple expressions in version 1.0 then you can use a simplified form of Dijkstra's algorithm. Then once you've parsed the expression, you need to evaluate it: use values that are linear expressions in x and interpret = as an operator with lowest possible precedence that means "subtract". The result is a linear expression in x that is equal to 0.
If you don't need complicated expressions then you can evaluate that simple example pretty much directly from left-to-right once you've tokenised it[*]:
x
x + 9
// set the "we've found minus sign" bit to negate the first thing that follows
x + 7 // and clear the negative bit
x + 3
2 * x + 3
// set the "we've found the equals sign" bit to negate everything that follows
3 * x + 3
3 * x - 2
3 * x - 1
3 * x - 4
4 * x - 4
Finally, solve a * x + b = 0 as x = - b/a.
[*] example tokenisation code, in Python:
acc = None
for idx, ch in enumerate(input):
if ch in '1234567890':
if acc is None: acc = 0
acc = 10 * acc + int(ch)
continue
if acc != None:
yield acc
acc = None
if ch in '+-=x':
yield ch
elif ch == ' ':
pass
else:
raise ValueError('illegal character "%s" at %d' % (ch, idx))
Alternative example tokenisation code, also in Python, assuming there will always be spaces between tokens as in the example. This leaves token validation to the parser:
return input.split()
ok some simple psuedo code that you could use to solve this problem
function(stinrgToParse){
arrayoftokens = stringToParse.match(RegexMatching);
foreach(arrayoftokens as token)
{
//now step through the tokens and determine what they are
//and store the neccesary information.
}
//Use the above information to do the arithmetic.
//count the number of times a variable appears positive and negative
//do the arithmetic.
//add up the numbers both positive and negative.
//return the result.
}
The first thing is to parse the string, to identify the various tokens (numbers, variables and operators), so that an expression tree can be formed by giving operator proper precedences.
Regular expressions can help, but that's not the only method (grammar parsers like boost::spirit are good too, and you can even run your own: its all a "find and recourse").
The tree can then be manipulated reducing the nodes executing those operation that deals with constants and by grouping variables related operations, executing them accordingly.
This goes on recursively until you remain with a variable related node and a constant node.
At the point the solution is calculated trivially.
They are basically the same principles that leads to the production of an interpreter or a compiler.
Consider:
from operator import add, sub
def ab(expr):
a, b, op = 0, 0, add
for t in expr.split():
if t == '+': op = add
elif t == '-': op = sub
elif t == 'x': a = op(a, 1)
else : b = op(b, int(t))
return a, b
Given an expression like 1 + x - 2 - x... this converts it to a canonical form ax+b and returns a pair of coefficients (a,b).
Now, let's obtain the coefficients from both parts of the equation:
le, ri = equation.split('=')
a1, b1 = ab(le)
a2, b2 = ab(ri)
and finally solve the trivial equation a1*x + b1 = a2*x + b2:
x = (b2 - b1) / (a1 - a2)
Of course, this only solves this particular example, without operator precedence or parentheses. To support the latter you'll need a parser, presumable a recursive descent one, which would be simper to code by hand.

Why is python skipping a line?

I'm pretty new to Python (just started teaching myself a week ago), so my debugging skills are weak right now. I tried to make a program that would ask a user-submitted number of randomly-generated multiplication questions, with factors between 0 and 12, like a multiplication table test.
import math
import random
#establish a number of questions
questions = int(input("\n How many questions do you want? "))
#introduce score
score = 1
for question in range(questions):
x = random.randrange(0,13)
y = random.randrange(0,13)
#make the numbers strings, so they can be printed with strings
abc = str(x)
cba = str(y)
print("What is " + abc + "*" + cba +"?")
z = int(input("Answer here: "))
print z
a = x*y
#make the answer a string, so it can be printed if you get one wrong
answer = str(a)
if z > a or z < a:
print ("wrong, the answer is " + answer)
print("\n")
#this is the line that's being skipped
score = score - 1/questions
else:
print "Correct!"
print ("\n")
finalscore = score*100
finalestscore = str(finalscore)
print (finalestscore + "%")
The idea was that every time the user gets a question wrong, score (set to 1) goes down by 1/question,so when multiplied by 100 it gives a percentage of questions wrong. However, no matter the number of questions or the number gotten wrong, score remains 1, so finalestscore remains 100. Line 26 used to be:
if math.abs(z)-math.abs(a) != 0:
but 2.7.3 apparently doesn't acknowledge that math has an abs function.
Such a simple accumulator pattern doesn't seem like it would be an issue, even for an older version of Python. Help?
Try score = score - 1.0/questions
The problem is that you're doing integer division, which truncates to the nearest integer, so 1/questions will always give 0.
The problem is that you are using integers for all of your calculations. In particular, when you calculate 1/questions, it truncates (rounds down) to an integer because both values in the calculation are integers.
To avoid this, you could instead use 1.0/questions to make the calculations use floating point numbers instead (and not truncate)

Translation from Maple to C++

Hey,
So I have a maple program which does bisection method and I have to convert it to C++. I tried converting it according to what the code generation help on the maple forums said but it kept throwing out errors. I would appreciate some help in this.
Thanks,
Here is the code for maple
Use the bisection method to solve the following mathematical problem:
a. smallest positive root of equation
f(x):=evalf(1/x-evalf(Pi)*cos(evalf(Pi)*x));
with delta = 10^-5 and eps = 10^-6
plot(f(x),x=.05..10.0);
From graph above we can conclude that given equation has smallest positive real root located between 0.0 and 2.0
To get their values with accuracy required we invoke bisection method with root isolation interval (0.01,2.0):
Bisect:=proc(funct_equation,ai,bi,Mi,epsfi,deltaxi) local k,M,a,b,u,v,w,c,e,epsf,deltax,feq, notsolved: M:=Mi: feq:=funct_equation: a:=ai: b:=bi: epsf:=epsfi: deltax:=deltaxi: notsolved:=true: u:=evalf(subs(x=a,feq)): v:=evalf(subs(x=b,feq)): printf("a=%+9.6f %+12.6e\nb=%+9.6f %+12.6e\n\n",a,u,b,v); e:=b-a; if (sign(u)<>sign(v)) then printf(" n x f\n"); for k from 1 by 1 while (k<M and notsolved) do:
e:=0.5*e;
c:=a+e;
w:=evalf(subs(x=c,feq)):
printf("%2d %+9.6f %+12.6e\n",k,c,w);
if (abs(e)<deltax or abs(w)<epsf) then
notsolved:=false:
else
if (sign(w) <> sign(u)) then
b:=c: v:=w:
else
a:=c: u:=w:
fi:
fi: od: printf("Root = %+9.6f function = %+12.6e\n",0.5*(a+b),evalf(subs(x=0.5*(a+b),feq))); fi: end: with(plots):
Warning, the name change coords has been redefined
Bisect(f(x),0.01,2.0,30,1.0e-6,1.0e-5):
You won't need that subs call, if you keep your feq as a procedure.
restart:
Bisect:=proc(func::procedure,ai,bi,Mi,epsfi,deltaxi)
local k::integer,
M::integer,
a,b,u,v,
w::float,
c,e,
epsf::float,
deltax,
notsolved;
M:=Mi:
a:=ai: b:=bi: epsf:=epsfi:
deltax:=deltaxi: notsolved:=true:
u:=func(a);
v:=func(b);
printf("a=%+9.6f %+12.6e\nb=%+9.6f %+12.6e\n\n",a,u,b,v);
e:=b-a;
if (sign(u)<>sign(v)) then
printf(" n x f\n");
for k from 1 by 1 while (k<M and notsolved) do
e:=0.5*e;
c:=a+e;
w:=func(c);
printf("%2d %+9.6f %+12.6e\n",k,c,w);
if (abs(e)<deltax or abs(w)<epsf) then
notsolved:=false:
else
if (sign(w) <> sign(u)) then
b:=c: v:=w:
else
a:=c: u:=w:
fi:
fi:
od:
printf("Root = %+9.6f function = %+12.6e\n",0.5*(a+b),func(0.5*(a+b),feq));
fi:
0.5*(a+b);
end:
with(plots):
f:=subs(Pi=evalf[16](Pi),proc(x::float) 1/x-Pi*cos(Pi*x); end proc);
Bisect(f,0.01,2.0,30,1.0e-6,1.0e-5);
f(%);
CodeGeneration[C](f);
CodeGeneration[C](Bisect);
Also, if you start with an expression for f, you can always turn it into an operator (a sort of procedure, but which too can be code-generated) using the unapply command.
For example, I could also have created the procedure f in the following ways. (Note that one of these produces a default 10-digits approximation to Pi in the generated C code, and the other a 16-digit approximation.)
f_expression := 1/x-Pi*cos(Pi*x);
f:=unapply(f_expression, [x::float]);
CodeGeneration[C](f);
f:=subs(Pi=evalf[16](Pi),unapply(f_expression, [x::float]));
CodeGeneration[C](f);