What does *I mean in sympy? [closed] - python

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 months ago.
Improve this question
pip install sympy
import math as m
from sympy import *
a,b = symbols('a b')
x1, y1 = (2, m.radians(152.6))
x2, y2 = (4, m.radians(163.7))
result = solve((a*sin(b*x1)-y1, a*sin(b*x2)-y2), dict=True)
print(result)
result is like below
[{a: -3.15571732546928 + 1.66055281406852e-26I, b: -0.502333320617012 + 2.31610571514848e-22I}, {a: -3.15571732546928 + 1.66055281406852e-26I, b: 2.63925933297278 + 2.24993126614424e-22I}, {a: 3.15571732546928 + 1.66055281406852e-26I, b: -2.63925933297278 + 2.24993126614424e-22I}, {a: 3.15571732546928 + 1.66055281406852e-26I, b: 0.502333320617012 + 2.31610571514848e-22I}]
What does this number mean?, especially 'e-26*I'

I, in Sympy, is the imaginary number constant. That is, the number defined to be the square root of negative one. From Wikipedia
[A] complex number is an element of a number system that extends the real numbers with a specific element denoted i
In your case, Sympy has found complex-valued solutions to your trigonometry equation. It's possible to apply trigonometric functions to complex numbers, and indeed often the only solution to an equation like that is a complex number.
The e part is a common format for displaying numbers in computer terminals. It's similar to scientific notation. The number 3e+8 should be read as three times ten to the eighth power. Likewise, 2e-1 should be read as two times ten to the negative-first power, or 0.2.
So, to take your first example,
-3.15571732546928 + 1.66055281406852e-26I
This is a complex number whose real part is -3.1557 and whose imaginary part is, frankly, a really small number (a decimal point followed by 25 zeroes and then some nonzero quantities).
What this likely means is that Sympy could not algebraically solve the equation, so it resorted to some numerical methods which could only get close. It's possible a = -pi is a solution, since -3.155 is pretty close to pi and the imaginary part of that number might as well be zero.

Related

Runs smoothly, but output is not correct [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Given 3 int values, a b c, return their sum. However, if any of the values is a teen -- in the range 13..19 inclusive -- then that value counts as 0, except 15 and 16 do not count as a teens. Write a separate helper "def fix_teen(n):"that takes in an int value and returns that value fixed for the teen rule. In this way, you avoid repeating the teen code 3 times (i.e. "decomposition"). Define the helper below and at the same indent level as the main no_teen_sum().
here's my code:
#Given 3 int values, a b c, return their sum. However, if any of the values is a teen -- in the range #13..19 inclusive -- then that value counts as 0, except 15 and 16 do not count as a teens. Write a #separate helper "def fix_teen(n):"that takes in an int value and returns that value fixed for the teen #rule. In this way, you avoid repeating the teen code 3 times (i.e. "decomposition"). Define the helper #below and at the same indent level as the main no_teen_sum().
def no_teen_sum(a, b, c):
a = fix_teen(a)
b = fix_teen(b)
c = fix_teen(c)
return(a+b+c)
def fix_teen(n):
if n<=13 and n>=19 and n != 15 and n != 16:
n = 0
return(n)
Don't know why this doesn't work. I'm pretty sure my code is correct but my algorithm is wrong. Also this is my first question please correct me if my format is incorrect.
You might mean if n>=13 and n<=19 and n != 15 and n != 16, because with the greater than and less than signs swapped no integer will ever fulfill the condition.
As Chris pointed out, you have the operators the wrong way around. You need if n>=13 and n<=19, but have if n<=13 and n>=19.

Strategies to avoid division by zero error [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Is there a best practice to avoid ZeroDivisionErrorin python? For instance, consider the following function:
def division (x,y):
return x / y
In this function if y is set to zero, the ZeroDivisionError is raised. One strategy would be to replace the denominator of the division by y+1, so the function would be:
def division (x,y):
return x / (y+1)
or the other strategy can be returning nan value if denominator is zero:
def division (x,y):
if y == 0:
return np.nan
else:
return x / y
What are the cons of the above strategies? Is there any other approach to avoid ZeroDivisionError? Exception handling is also a popular solution for this problem, but I'm more looking for prevention strategy not intervention.
This follows the same conditioning strategy, but you can use this approach:
def division(x, y):
return x/y if y else 0
Con of your add one strategy is that if y is a small number (not -1) then your results will be very incorrect. Only sort of works when y is very large.
Con of returning NaN is that you need to document this clearly for the person calling your function. np.nan can surprise the caller. For example what is expected when you do comparison like division(1, 0) == division(2,0)
Raising an error is the right thing to do and let the caller handle according to their rules.
Keep in mind that numpy.true_divide() never returns ZeroDivisionError. Returns inf. instead.
i.e
a = [1,2,3]
b = [0,1,2]
np.true_divide(a, b)
RuntimeWarning: divide by zero encountered in true_divide
array([inf, 2. , 1.5])
It usually means that your algorithm is not carefully designed. Just taking care of +/- 0 is not going to help you in most cases. Almost every algorithm in literature deals with division by zero either by adding an ε to the absolute value or by thresholding the absolute value. One could also avoid such cases by limiting processing only on those values where denominator is significant.

Round negative float numbers to floats [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am trying to round some negative floating numbers, the format i want is like the below print/format way, not the round. The problem is that the print approach is not "clean", since it outputs a string with spaces, I got this code from another similar question here in Stackoverflow. The question is how to format/round the numbers like the print below. Thank you
theta = 0.33161255787892263
math = 0 + (1-0) * (1-math.cos(theta))**5
round(math,8) # Result: 4.8e-07 #
print("{:18.8f}".format(math)) # Result: ' 0.00000048' #
You say "I want the result of the print but in a float number not string" and "The result returns to a negative power floating point number, i want to keep the decimal format as the string". But you can't do that because you have no control over the internal representation of a float: they are all stored in a binary form of scientific notation. See the Wikipedia article on floating-point numbers for details.
So it doesn't matter whether you do
v = 0.00000048
or
v = 4.8e-07
both of those statements have an identical effect.
Note that many fractional numbers that terminate when written in decimal may repeat when written in binary. The only fractions that terminate when written in binary are of the form n / (2 ** b), where n and b are integers. Thus even an innocuous-looking number like 0.2 doesn't terminate when converted to binary. (See the Wiki link for a fuller explanation). Because of this issue it's generally not a good idea to round floating-point numbers until you've finished all calculations with them.
If you convert a string to float and back again it has to be converted from decimal to binary and back again. So such an operation shouldn't be used in an attempt to "clean up" a number because of the possible rounding errors at each conversion step.
Of course, sometimes you do need to apply rounding to a float that you are going to continue calculating with, but if so, you should proceed with caution and make sure you really do understand what you're doing to your data.
...
There are a few other strange things with the code you posted.
math = 0 + (1-0) * (1-math.cos(theta))**5
Firstly, you should not use the name of a module that you've imported as a variable name. After the above statement is executed math now refers to the result of the calculation, not the math module, so if you tried to do x = math.cos(0.5) you'd get an error. Similarly, don't use int, str, list, etc as variable names.
Secondly, the 0 + (1-0) * is virtually useless. So the above statement could be re-written as
result = (1 - math.cos(theta)) ** 5
And the whole code snippet would become
#! /usr/bin/env python
import math
theta = 0.33161255787892263
result = (1 - math.cos(theta)) ** 5
print round(result, 8)
print("{0:.8f}".format(result))
output
4.8e-07
0.00000048

How to calculate sine and cosine without importing math? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I started programming in python not too long ago and I am having trouble with a part of a program. The program will ask for input from the user and he can input: A, B, C, M, or Q. I have completed the A, M, and Q part but I can't figure out how to do the parts for B (calculate the sine of the number you want) and C (calculate the sine).
All the information I was given was:
The power series approximation for the sine of X can be expressed as:
sine(X) = X – (X3/3!) + (X5/5!) – (X7/7!) + (X9/9!) .... Note that an
individual term in that power series can be expressed as: (-1)k *
X2k+1 / (2k+1)! where k = 0, 1, 2, 3, ….
Oooh, and (but for this a while loop should do right?):
When computing the sine of X or the cosine of X, the program will expand the power series
until the absolute value of the next term in the series is less than 1.0e-8 (the specified epsilon).
That term will not be included in the approximation.
And I can't use import math.
Can anyone give me an idea of how I can do this? I sincerely have no idea of where to even start hahaha.
Thanks in advance!
***Hey guys, I've been trying to do this for the last 3 hours. I'm really new to programming and some of yours answers made it a bit more understandable for me but my program is not working, I really don't know how to do this. And yes, I went to speak with a tutor today but he didn't know either. So yeah, I guess I'll just wait until I get the program graded by my teacher and then I can ask him how it was supposed to be done. Thank you for all the answers though, I appreciate them! :)
>>> e = 2.718281828459045
>>> X = 0.1
>>> (e**(X*1j)).imag # sin(X)
0.09983341664682815
>>> (e**(X*1j)).real # cos(X)
0.9950041652780258
Verify
>>> from math import sin, cos
>>> sin(X)
0.09983341664682815
>>> cos(X)
0.9950041652780258
You'll probably get better marks if you sum up the series explicitly though
result = 0
n = 1
while True:
term = ...
result += term
if term <= epsilon:
break
n += 2
It seems that you aren't supposed to import math because you are supposed to write your own function to compute sine. You are supposed to use the power series approximation.
I suggest you start by writing a factorial function, then write a loop that uses this factorial function to compute the power series.
If you still can't figure it out, I suggest you talk to your teacher or a teacher's assistant.
Since you have a condition to finish the loop last_term < 1.0e-8, you should use a while:
while last_term > 1.0e-8:
You will need a counter to keep the count of k (starting from 0) and a variable to keep the last term:
k = 10 # some initial value
last_term = 0
while ...:
last_term = ... # formula here
and also a result variable, let' say sin_x:
while ...:
...
sin_x += last_term
Note: In the formula you are using factorial, so will need to define a function that computes the factorial of a number, and use it properly.

Pi calculation in python [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
n=iterations
for some reason this code will need a lot more iterations for more accurate result from other codes, Can anyone explain why this is happening? thanks.
n,s,x=1000,1,0
for i in range(0,n,2):
x+=s*(1/(1+i))*4
s=-s
print(x)
As I mentioned in a comment, the only way to speed this is to transform the sequence. Here's a very simple way, related to the Euler transformation (see roippi's link): for the sum of an alternating sequence, create a new sequence consisting of the average of each pair of successive partial sums. For example, given the alternating sequence
a0 -a1 +a2 -a3 +a4 ...
where all the as are positive, the sequences of partial sums is:
s0=a0 s1=a0-a1 s2=a0-a1+a2 s3=a0-a1+a2-a3 s4=a0-a1+a2-a3+a4 ...
and then the new derived sequence is:
(s0+s1)/2 (s1+s2)/2 (s2+s3)/2 (s3+s4)/2 ...
That can often converge faster - and the same idea can applied to this sequence. That is, create yet another new sequence averaging the terms of that sequence. This can be carried on indefinitely. Here I'll take it one more level:
from math import pi
def leibniz():
from itertools import count
s, x = 1.0, 0.0
for i in count(1, 2):
x += 4.0*s/i
s = -s
yield x
def avg(seq):
a = next(seq)
while True:
b = next(seq)
yield (a + b) / 2.0
a = b
base = leibniz()
d1 = avg(base)
d2 = avg(d1)
d3 = avg(d2)
for i in range(20):
x = next(d3)
print("{:.6f} {:8.4%}".format(x, (x - pi)/pi))
Output:
3.161905 0.6466%
3.136508 -0.1619%
3.143434 0.0586%
3.140770 -0.0262%
3.142014 0.0134%
3.141355 -0.0076%
3.141736 0.0046%
3.141501 -0.0029%
3.141654 0.0020%
3.141550 -0.0014%
3.141623 0.0010%
3.141570 -0.0007%
3.141610 0.0005%
3.141580 -0.0004%
3.141603 0.0003%
3.141585 -0.0003%
3.141599 0.0002%
3.141587 -0.0002%
3.141597 0.0001%
3.141589 -0.0001%
So after just 20 terms, we've already got pi to about 6 significant digits. The base Leibniz sequence is still at about 2 digits correct:
>>> next(base)
3.099944032373808
That's an enormous improvement. A key point here is that the partial sums of the base Leibniz sequence give approximations that alternate between "too big" and "too small". That's why averaging them gets closer to the truth. The same (alternating between "too big" and "too small") is also true of the derived sequences, so averaging their terms also helps.
That's all hand-wavy, of course. Rigorous justification probably isn't something you're interested in ;-)
That is because you are using the Leibniz series and it is known to converge very (very) slowly.

Categories

Resources