Sympy integration giving NaN as output - integration

I am fairly new to sympy and hoping if someone could guide me on the right approach. As mentioned the following when integrated gives a NaN output. Is this a mathematics error, sympy limitation or user error?

Since NaN isn't a correct answer for that integral, it is a SymPy error. But it's caused by a suboptimal setup. SymPy finds it difficult to handle expressions with floating-point numbers, because floating-point arithmetics is different from mathematical rules of arithmetics (addition is not associative, for example). This is particularly true for expressions with such constants in an exponent.
For this reason, it's best to keep the floating point constants out of the computations, including them at the end. Instead of
integrate((0.2944/z**0.22+1.0)*(1.939*log(z/10) +17.7), z)
write
a, b, c, d, e = symbols('a b c d e', positive=True)
values = {a: 0.2944, b: 0.22, c: 1.0, d: 1.939, e: 17.7}
expr = integrate((a/z**b + c) * (d*log(z/10) + e), z)
print(expr.subs(values).simplify())
which prints
0.731848205128205*z**0.78*log(z) + 4.05720568750119*z**0.78 + 1.939*z**1.0*log(z) + 11.2962875046845*z**1.0

Related

Is it possible find the values ​of the two variables a and x in the function y = (a ^ k) ^ (x ^ k), i know only the y and the k

I would like to know if it is possible to create a function, using logic gates for binary numbers, such that i can go back to the two variables a and x, knowing only y and k.
I used the XOR logic gate but, if this is indeed possible, you can also change it to any other gate, I accept any kind of advice!
y = (a ^ k) ^ (x ^ k)
That's a SAMPLE of the function that i must find, if it can be solved in other simpler ways let me know! Thank you
i'm assuming that ^ here means xor and not exponentiation.
Remember that ^ is both associative and commutative, so
y = (a ^ k) ^ (x ^ k) == a ^ x ^ k ^ k = a ^ x ^ (k ^ k) = a ^ x ^ 0 = a ^ x
The value of k is completely irrelevant in this expression, so knowing the value of k tells you absolutely nothing.
Knowing the values of two of a, x, or y, you find find the third by xor-ing the other two. You cannot find the value of k if you don't know it.
You can, in a sense. What we know about the normal math we have encountered our whole lives is not the same here, so solving for a and x will not be so explicit. Firstly, there is not a nice concept of moving variables from one side of the equation to the other in boolean algebra. Second, the XOR function is not a continuous function, therefore it can only be expressed as a piecewise function. What that all means is solving for a and x is not going to happen like we're used to.
Let's break it apart to make it more clear.
y = f1 ^ f2
where f1 = (a^k)
where f2 = (x^k)
All we did here was to make a smaller function for each parenthesis.
Let's define f1 (XOR).
f1 = 0, a=k
f1 = 1, a!=k
Let's define f2 (XOR).
f2 = 0, x=k
f2 = 1, x!=k
Now, let's define y (XOR)
y = 0, f1=f2
y = 1, f1!=f2
If you know y, then you can determine whether f1 and f2 are equal or not. Since f1 and f2 are constructed the same way, they are identical except for their input arguments a and x. From this point, if you know k, you can show that if f1=f2, then a=x. You can also show that if f1!=f2, then a!=x. You can say how a and x are related, but unfortunately, you cannot determine their values. I urge you to try plugging it in yourself, you will find a and x can have two different values for each value of y.

Wrong result of sympy integration

This expression returns zero, but it shouldn`t.
P = x^6-14x^4+49x^2-36
integrate(1/P, (x, 1/3, 1/2))
I also used expand on expression, without any result.
Am i doing something wrong or is this a bug?
This works:
from sympy import *
x = symbols('x')
P = x**6-14*x**4+49*x**2-36
I = integrate(1/expand(P), (x, S.One/3, S.One/2))
I get the result:
In [5]: I
Out[5]: -3*log(3)/80 - log(7)/48 - log(2)/48 - log(8)/240 + log(10)/240 + log(4)/48 + 3*log(5)/80
In [6]: I.n()
Out[6]: -0.00601350282195297
In alternative, you could run the command isympy -i, this will run a SymPy prompt that converts all Python integers to SymPy integers before the input gets evaluated by the SymPy parser.
Python integer division is different between Python 2 and Python 3, the first returns and integer, the second returns a floating point number. Both versions are different to SymPy integer division, which returns fractions. To use SymPy division, you need to make sure that at least one among the dividend and divisor are SymPy objects.

Double-precision error using Dislin

I get the following error when trying to compile:
call qplot (Z, B, m + 1)
1
Error: Type mismatch in argument 'x' at (1); passed REAL(8) to REAL(4)
Everything seems to be in double precision so I can't help but think it is a Dislin error, especially considering that it appears with reference to a Dislin statement. What am I doing wrong? My code is the following:
program test
use dislin
integer :: i
integer, parameter :: n = 2
integer, parameter :: m = 5000
real (kind = 8) :: X(n + 1), Z(0:m), B(0:m)
X(1) = 1.D0
X(2) = 0.D0
X(3) = 2.D0
do i = 0, m
Z(i) = -1.D0 + (2.D0*i) / m
B(i) = f(Z(i))
end do
call qplot (Z, B, m + 1)
read(*,*)
contains
real (kind = 8) function f(t)
implicit none
real (kind = 8), intent(in) :: t
real (kind = 8), parameter :: pi = Atan(1.D0)*4.D0
f = cos(pi*t)
end function f
end program
From the DISLIN manual I read that qplot requires (single precision) floats:
QPLOT connects data points with lines.
The call is: CALL QPLOT (XRAY, YRAY, N) level 0, 1
or: void qplot (const float *xray, const float *yray, int n);
XRAY, YRAY are arrays that contain X- and Y-coordinates.
N is the number of data points.
So you need to convert Z and B to real:
call qplot (real(Z), real(B), m + 1)
Instead of using fixed numbers for the kind of numbers (which vary between compilers), please consider using the ISO_Fortran_env module and the pre-defined constants REAL32 and REAL64.
The qplot routine requires a default real. You can convert your data
call qplot(real(Z), real(B), m + 1)
I second the remark with kind = 8, it is very ugly, if you insist on 8 at least declare a constant
integer, parameter :: rp = 8
and use
real(rp) ::
As the first two answers explain, the standard versions of the dislin routines require single precision arguments. I find it most convenient to use these since I may have single or double arguments, using the real technique to convert the type of double variables. It seems unlikely that the lost precision will be perceptible on a graph. However, if you wish to work exclusively in double precision, there is an alternative set of routines. They have the same names, but take double precision arguments. To obtain them, link in the library "dislin_d".

Binary to decimal - prolog

I found this on stack: reversible "binary to number" predicate
But I don't understand
:- use_module(library(clpfd)).
binary_number(Bs0, N) :-
reverse(Bs0, Bs),
binary_number(Bs, 0, 0, N).
binary_number([], _, N, N).
binary_number([B|Bs], I0, N0, N) :-
B in 0..1,
N1 #= N0 + (2^I0)*B,
I1 #= I0 + 1,
binary_number(Bs, I1, N1, N).
Example queries:
?- binary_number([1,0,1], N).
N = 5.
?- binary_number(Bs, 5).
Bs = [1, 0, 1] .
Could somebody explain me the code
Especialy this : binary_number([], _, N, N). (The _ )
Also what does library(clpfd) do ?
And why reverse(Bs0, Bs) ? I took it away it still works fine...
thx in advance
In the original, binary_number([], _, N, N)., the _ means you don't care what the value of the variable is. If you used, binary_number([], X, N, N). (not caring what X is), Prolog would issue a singleton variable warning. Also, what this predicate clause says is that when the first argument is [] (the empty list), then the 3rd and 4th arguments are unified.
As explained in the comments, use_module(library(clpfd)) causes Prolog to use the library for Constraint Logic Programming over Finite Domains. You can also find lots of good info on it via Google search of "prolog clpfd".
Normally, in Prolog, arithmetic expressions of comparison require that the expressions be fully instantiated:
X + Y =:= Z + 2. % Requires X, Y, and Z to be instantiated
Prolog would evaluate and do the comparison and yield true or false. It would throw an error if any of these variables were not instantiated. Likewise, for assignment, the is/2 predicate requires that the right hand side expression be fully evaluable with specific variables all instantiated:
Z is X + Y. % Requires X and Y to be instantiated
Using CLPFD you can have Prolog "explore" solutions for you. And you can further specify what domain you'd like to restrict the variables to. So, you can say X + Y #= Z + 2 and Prolog can enumerate possible solutions in X, Y, and Z.
As an aside, the original implementation could be refactored a little to avoid the exponentiation each time and to eliminate the reverse:
:- use_module(library(clpfd)).
binary_number(Bin, N) :-
binary_number(Bin, 0, N).
binary_number([], N, N).
binary_number([Bit|Bits], Acc, N) :-
Bit in 0..1,
Acc1 #= Acc*2 + Bit,
binary_number(Bits, Acc1, N).
This works well for queries such as:
| ?- binary_number([1,0,1,0], N).
N = 10 ? ;
no
| ?- binary_number(B, 10).
B = [1,0,1,0] ? ;
B = [0,1,0,1,0] ? ;
B = [0,0,1,0,1,0] ? ;
...
But it has termination issues, as pointed out in the comments, for cases such as, Bs = [1|_], N #=< 5, binary_number(Bs, N). A solution was presented by #false which simply modifies the above helps solve those termination issues. I'll reiterate that solution here for convenience:
:- use_module(library(clpfd)).
binary_number(Bits, N) :-
binary_number_min(Bits, 0,N, N).
binary_number_min([], N,N, _M).
binary_number_min([Bit|Bits], N0,N, M) :-
Bit in 0..1,
N1 #= N0*2 + Bit,
M #>= N1,
binary_number_min(Bits, N1,N, M).

Plotting a 3D function with Octave

I am having a problem graphing a 3d function - when I enter data, I get a linear graph and the values don't add up if I perform the calculations by hand. I believe the problem is related to using matrices.
INITIAL_VALUE=999999;
INTEREST_RATE=0.1;
MONTHLY_INTEREST_RATE=INTEREST_RATE/12;
# ranges
down_payment=0.2*INITIAL_VALUE:0.1*INITIAL_VALUE:INITIAL_VALUE;
term=180:22.5:360;
[down_paymentn, termn] = meshgrid(down_payment, term);
# functions
principal=INITIAL_VALUE - down_payment;
figure(1);
plot(principal);
grid;
title("Principal (down payment)");
xlabel("down payment $");
ylabel("principal $ (amount borrowed)");
monthly_payment = (MONTHLY_INTEREST_RATE*(INITIAL_VALUE - down_paymentn))/(1 - (1 + MONTHLY_INTEREST_RATE)^-termn);
figure(2);
mesh(down_paymentn, termn, monthly_payment);
title("monthly payment (principal(down payment)) / term months");
xlabel("principal");
ylabel("term (months)");
zlabel("monthly payment");
The 2nd figure like I said doesn't plot like I expect. How can I change my formula for it to render properly?
I tried your script, and got the following error:
error: octave_base_value::array_value(): wrong type argument `complex matrix'
...
Your monthly_payment is a complex matrix (and it shouldn't be).
I guess the problem is the power operator ^. You should be using .^ for element-by-element operations.
From the documentation:
x ^ y
x ** y
Power operator. If x and y are both scalars, this operator returns x raised to the power y. If x is a scalar and y is a square matrix, the result is computed using an eigenvalue expansion. If x is a square matrix. the result is computed by repeated multiplication if y is an integer, and by an eigenvalue expansion if y is not an integer. An error results if both x and y are matrices.
The implementation of this operator needs to be improved.
x .^ y
x .** y
Element by element power operator. If both operands are matrices, the number of rows and columns must both agree.