With a simple function such as
function fun(x::Real, y::Real)
x, y
end
that i want to call using pmap() by doing
pmap(fun, [x for x=0:.1:2], [y for y=4:-.1:2])
Julia gives this error
ERROR: LoadError: MethodError: Cannot `convert` an object of type Tuple{Float64,Float64} to an object of type AbstractFloat
This may have arisen from a call to the constructor AbstractFloat(...),
since type constructors fall back to convert methods.
I don't really get what's happening here.
According to some research I've done:
It's well-established that to call map on an N-argument function, you pass N lists (or whatever collection) to map:
julia> map(+, (1,2), (3,4))
(4,6)
What's wrong then?
Which version of Julia are you using? Please update to the latest stable release (0.6.x), as this work fine with the current release, this esample was ran at JuliaBox:
https://juliabox.com
jrun#notebook-0hnhf:/home/jrun$ julia
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: https://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _' | |
| | |_| | | | (_| | | Version 0.6.2 (2017-12-13 18:08 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-pc-linux-gnu'
julia> function fun(x::Real, y::Real)
x, y
end
fun (generic function with 1 method)
julia> pmap(fun, [x for x = 0:.1:2], [y for y = 4:-.1:2])
21-element Array{Tuple{Float64,Float64},1}:
(0.0, 4.0)
(0.1, 3.9)
(0.2, 3.8)
(0.3, 3.7)
(0.4, 3.6)
(0.5, 3.5)
(0.6, 3.4)
(0.7, 3.3)
(0.8, 3.2)
(0.9, 3.1)
(1.0, 3.0)
(1.1, 2.9)
(1.2, 2.8)
(1.3, 2.7)
(1.4, 2.6)
(1.5, 2.5)
(1.6, 2.4)
(1.7, 2.3)
(1.8, 2.2)
(1.9, 2.1)
(2.0, 2.0)
If you are not going to transform or filters the collected elements of the range, then you could also simply call collect(4:-.1:2) instead of [y for y = 4:-.1:2].
If you just need to iterate over the values of the range, then you don't even need to collect the values, just use the ranges as is instead, ie:
pmap(fun, 0:.1:2, 4:-.1:2)
Related
In Julia, I use Reduce package to do integration since Julia Symbolics.jl does not have integrate command in it.
But I am not able to figure how to convert the output (the anti derivative) to Julia symbolic expression so I can use it inside Julia symbolic, and not using the Reduce package.
This is what I tried
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.7.1 (2021-12-22)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using Symbolics
julia> using Reduce
julia> #variables x
1-element Vector{Num}:
x
#use Reduce to do the integration
julia> output = :(int(sin(x),x)) |> rcall
:(-(cos(x)))
julia> typeof(output)
Expr
Now, I want to use the output -cos(x) as symbolic expression using Julia Symbolics. How to convert it?
Now it gives an error as is
julia> Symbolics.simplify(output^2)
ERROR: MethodError: no method matching ^(::Expr, ::Int64)
Closest candidates are:
^(::Union{AbstractChar, AbstractString}, ::Integer) at G:\nabbasi\data\CDROM\JULIA_language\julia-1.7.1-win64\julia-1.7.1\share\julia\base\strings\basic.jl:721
^(::LinearAlgebra.Diagonal, ::Integer) at G:\nabbasi\data\CDROM\JULIA_language\julia-1.7.1-win64\julia-1.7.1\share\julia\stdlib\v1.7\LinearAlgebra\src\diagonal.jl:196
^(::LinearAlgebra.Diagonal, ::Real) at G:\nabbasi\data\CDROM\JULIA_language\julia-1.7.1-win64\julia-1.7.1\share\julia\stdlib\v1.7\LinearAlgebra\src\diagonal.jl:195
...
Stacktrace:
[1] literal_pow(f::typeof(^), x::Expr, #unused#::Val{2})
# Base .\intfuncs.jl:325
[2] top-level scope
# REPL[9]:1
This is the same output, but now it is Julia Symbolics expression:
julia> f=-cos(x)
-cos(x)
julia> typeof(f)
Num
julia> Symbolics.simplify( f^2)
cos(x)^2
How does one convert output of Reduce expression to Julia Symbolics expression, may be for further processing?
It is possible to convert the Reduce output to string
julia> g=string(output)
"-(cos(x))"
But do not know how to convert the above string now to Symbolics expression. parse does not work. May be there is different command?
References
Reduce Julia package https://docs.juliahub.com/Reduce/wEGBP/1.2.5/
Julia Symbolics package https://symbolics.juliasymbolics.org/dev/
So it looks like these two packages (Reduce and Symbolics) are using rather different formats for their symbolic expressions. Reduce is using Julia's native Expr type, the same type used to represent Julia code itself, while Symbolics is using an approach where calling a function on one or more special variable designated with #variables will return an object that records the operations performed on those variables:
julia> using Reduce, Symbolics
julia> a = :(-(cos(x)))
:(-(cos(x)))
julia> #variables x;
julia> b = -(cos(x))
-cos(x)
julia> typeof(a)
Expr
julia> typeof(b)
Num
To see and compare what is actually inside these two different objects a and b, we can use Julia's very useful dump function:
julia> dump(a)
Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol -
2: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol cos
2: Symbol x
julia> dump(b)
Num
val: SymbolicUtils.Mul{Real, Int64, Dict{Any, Number}, Nothing}
coeff: Int64 -1
dict: Dict{Any, Number}
slots: Array{UInt8}((16,)) UInt8[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00]
keys: Array{Any}((16,))
1: #undef
2: #undef
3: #undef
4: #undef
5: #undef
...
12: #undef
13: SymbolicUtils.Term{Real, Nothing}
f: cos (function of type typeof(cos))
arguments: Array{SymbolicUtils.Sym{Real, Base.ImmutableDict{DataType, Any}}}((1,))
1: SymbolicUtils.Sym{Real, Base.ImmutableDict{DataType, Any}}
name: Symbol x
metadata: Base.ImmutableDict{DataType, Any}
parent: Base.ImmutableDict{DataType, Any}
key: Symbolics.VariableSource <: Any
value: Tuple{Symbol, Symbol}
metadata: Nothing nothing
hash: Base.RefValue{UInt64}
x: UInt64 0xd47301bdec8cde1c
14: #undef
15: #undef
16: #undef
vals: Array{Number}((16,)) Number[#undef, #undef, #undef, #undef, #undef, #undef, #undef, #undef, #undef, #undef, #undef, #undef, 1, #undef, #undef, #undef]
ndel: Int64 0
count: Int64 1
age: UInt64 0x0000000000000001
idxfloor: Int64 13
maxprobe: Int64 0
sorted_args_cache: Base.RefValue{Any}
x: Array{Any}((2,))
1: Int64 -1
2: SymbolicUtils.Term{Real, Nothing}
f: cos (function of type typeof(cos))
arguments: Array{SymbolicUtils.Sym{Real, Base.ImmutableDict{DataType, Any}}}((1,))
1: SymbolicUtils.Sym{Real, Base.ImmutableDict{DataType, Any}}
name: Symbol x
metadata: Base.ImmutableDict{DataType, Any}
parent: Base.ImmutableDict{DataType, Any}
key: Symbolics.VariableSource <: Any
value: Tuple{Symbol, Symbol}
metadata: Nothing nothing
hash: Base.RefValue{UInt64}
x: UInt64 0xd47301bdec8cde1c
hash: Base.RefValue{UInt64}
x: UInt64 0x0000000000000000
metadata: Nothing nothing
and they are indeed quite different.
That's not to say that you can't use the two packages together though. Since an Expr is the type used to represent Julia code as data, all you need to do is evaluate that Expr to obtain the same result as if you had called the functions therein (going the other way would be another matter, though!). So we can write:
julia> output = :(int(sin(x),x)) |> rcall
:(-(cos(x)))
julia> output = eval(output)
-cos(x)
julia> Symbolics.simplify(output^2)
cos(x)^2
Alternatively, you could add the ^2 to output while keeping it in Expr form by using one of Julia's many ways of manipulating Exprs, and only later eval it when you need to pass it to Symbolics:
julia> output = :(int(sin(x),x)) |> rcall
:(-(cos(x)))
julia> output_squared = :($output^2) # interpolate one Expr into another
:((-(cos(x))) ^ 2)
julia> Symbolics.simplify(eval(output_squared))
cos(x)^2
There may more performant approaches of which I am unaware, since I have not extensively used either package, and using eval is arguably a bit of a hack. But, this should work without error for any case where the functions in your Reduce expression are defined Julia functions that Symbolics knows about (and as long as you're evaluating them in the right scope).
For teaching purposes, how would you write a "julian" Julia 1.0+ code to print the first 2,000 digits of pi past the decimal point? The result, in the Julia REPL, should match this pi website.
The expected output is:
julia> include("solution.jl")
Pi to 2,000 digits to right of decimal point is:
3.
14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196
44288109756659334461284756482337867831652712019091
45648566923460348610454326648213393607260249141273
72458700660631558817488152092096282925409171536436
78925903600113305305488204665213841469519415116094
33057270365759591953092186117381932611793105118548
07446237996274956735188575272489122793818301194912
98336733624406566430860213949463952247371907021798
60943702770539217176293176752384674818467669405132
00056812714526356082778577134275778960917363717872
14684409012249534301465495853710507922796892589235
42019956112129021960864034418159813629774771309960
51870721134999999837297804995105973173281609631859
50244594553469083026425223082533446850352619311881
71010003137838752886587533208381420617177669147303
59825349042875546873115956286388235378759375195778
18577805321712268066130019278766111959092164201989
38095257201065485863278865936153381827968230301952
03530185296899577362259941389124972177528347913151
55748572424541506959508295331168617278558890750983
81754637464939319255060400927701671139009848824012
85836160356370766010471018194295559619894676783744
94482553797747268471040475346462080466842590694912
93313677028989152104752162056966024058038150193511
25338243003558764024749647326391419927260426992279
67823547816360093417216412199245863150302861829745
55706749838505494588586926995690927210797509302955
32116534498720275596023648066549911988183479775356
63698074265425278625518184175746728909777727938000
81647060016145249192173217214772350141441973568548
16136115735255213347574184946843852332390739414333
45477624168625189835694855620992192221842725502542
56887671790494601653466804988627232791786085784383
82796797668145410095388378636095068006422512520511
73929848960841284886269456042419652850222106611863
06744278622039194945047123713786960956364371917287
46776465757396241389086583264599581339047802759009
The surprising key to solving this question with very little code, to a relative newcomer to Julia, like myself, and maybe someone else, is that the pi constant in Julia is not hard-coded to some number of digits, like many other languages. In Julia, the pi constant "changes" its precision, based on the underlying precision of the current operation, e.g., Julia's current BigFloat precision in this example.
So if we set the BigFloat precision to 2,001 decimal digits and do a BigFloat outcome operation with pi, we should get the desired answer.
The simplest way to do this operation, that I am aware of, is to just change pi to the BigFloat type. This will result in an outcome type of BigFloat, as shown by this code.
julia> VERSION
v"1.1.0"
julia> typeof(BigFloat(pi)) # big"1" * pi also works
BigFloat
The original question can be solved with this method, as shown by the code below. Note that using 2,002 vs. 2,001 decimal digits in the setprecision input calculation, may not be needed, but I used at least one extra digit as a "guard" digit, for any potential rounding.
setprecision(Int(ceil(log2(10) * 2002))) do
pi_str = string(BigFloat(pi))[1:3+1999]
digits_str = pi_str[3:3+1999]
println("Pi to 2,000 digits to right of decimal point is:")
println(pi_str[1:2])
for start in 1:50:1951
println(digits_str[start:start+49])
end
end
I find it remarkable that Julia can solve this problem with so little code! I also tried this for 10,000 digits past the decimal point, and it worked great.
Here is the output:
julia> include("solution.jl")
Pi to 2,000 digits to right of decimal point is:
3.
14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196
44288109756659334461284756482337867831652712019091
45648566923460348610454326648213393607260249141273
72458700660631558817488152092096282925409171536436
78925903600113305305488204665213841469519415116094
33057270365759591953092186117381932611793105118548
07446237996274956735188575272489122793818301194912
98336733624406566430860213949463952247371907021798
60943702770539217176293176752384674818467669405132
00056812714526356082778577134275778960917363717872
14684409012249534301465495853710507922796892589235
42019956112129021960864034418159813629774771309960
51870721134999999837297804995105973173281609631859
50244594553469083026425223082533446850352619311881
71010003137838752886587533208381420617177669147303
59825349042875546873115956286388235378759375195778
18577805321712268066130019278766111959092164201989
38095257201065485863278865936153381827968230301952
03530185296899577362259941389124972177528347913151
55748572424541506959508295331168617278558890750983
81754637464939319255060400927701671139009848824012
85836160356370766010471018194295559619894676783744
94482553797747268471040475346462080466842590694912
93313677028989152104752162056966024058038150193511
25338243003558764024749647326391419927260426992279
67823547816360093417216412199245863150302861829745
55706749838505494588586926995690927210797509302955
32116534498720275596023648066549911988183479775356
63698074265425278625518184175746728909777727938000
81647060016145249192173217214772350141441973568548
16136115735255213347574184946843852332390739414333
45477624168625189835694855620992192221842725502542
56887671790494601653466804988627232791786085784383
82796797668145410095388378636095068006422512520511
73929848960841284886269456042419652850222106611863
06744278622039194945047123713786960956364371917287
46776465757396241389086583264599581339047802759009
Here is the short code to print out Pi. It is in a file called "pi_print.jl" and it contains the actual ALGORITHM for calculating the digits of Pi using bigint.
function main()
firsttime_flag = true
counter = 2000
(k, a, b, a1, b1) = (BigInt(2), BigInt(4), BigInt(1), BigInt(12), BigInt(4))
while counter > 0
(p, q, k) = (k*k, BigInt(2)*k+BigInt(1), k+BigInt(1))
(a, b, a1, b1) = (a1, b1, p*a+q*a1, p*b+q*b1)
(d,d1) = ( div(a,b),div(a1,b1) )
while d == d1 && counter > 0
if firsttime_flag
firsttime_flag = false
println("Pi to 2,000 digits to the right of decimal point is:")
write(stdout,string(d))
println(".")
else
write(stdout,string(d))
counter = counter - 1
end
(a,a1) = ( BigInt(10) * (a % b), BigInt(10) * (a1 % b1) )
(d,d1) = ( div(a,b),div(a1,b1) )
end
end
end
main()
Here is the output (which I have truncated)
$ julia pi_print.jl
Pi to 2,000 digits to the right of decimal point is:
3.
1415926535897932384626433832795028841971693993751058209749445923078164
0628620899862141592653589793238462643383279502884197169399375105820974
...
using REPL
$ julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.0.3 (2018-12-18)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> include("pi_print.jl")
Pi to 2,000 digits to the right of decimal point is:
3.
1415926535897932384626433832795028841971693993751058209749445923078164062862
0899862803482534211706798214808651328230664709384460955058223172535940812848
1117450284102701938521105559644622948954930381964428810975665933446128475648
2337867831652712019091456485669234603486104543266482133936072602491412737245
8700660631558817488152092096282925409171536436789259036001133053054882046652
1384146951941511609433057270365759591953092186117381932611793105118548074462
3799627495673518857527248912279381830119491298336733624406566430860213949463
9522473719070217986094370277053921717629317675238467481846766940513200056812
7145263560827785771342757789609173637178721468440901224953430146549585371050
7922796892589235420199561121290219608640344181598136297747713099605187072113
4999999837297804995105973173281609631859502445945534690830264252230825334468
5035261931188171010003137838752886587533208381420617177669147303598253490428
7554687311595628638823537875937519577818577805321712268066130019278766111959
0921642019893809525720106548586327886593615338182796823030195203530185296899
5773622599413891249721775283479131515574857242454150695950829533116861727855
8890750983817546374649393192550604009277016711390098488240128583616035637076
6010471018194295559619894676783744944825537977472684710404753464620804668425
9069491293313677028989152104752162056966024058038150193511253382430035587640
2474964732639141992726042699227967823547816360093417216412199245863150302861
8297455570674983850549458858692699569092721079750930295532116534498720275596
0236480665499119881834797753566369807426542527862551818417574672890977772793
8000816470600161452491921732172147723501414419735685481613611573525521334757
4184946843852332390739414333454776241686251898356948556209921922218427255025
4256887671790494601653466804988627232791786085784383827967976681454100953883
7863609506800642251252051173929848960841284886269456042419652850222106611863
0674427862203919494504712371378696095636437191728746776465757396241389086583
264599581339047802759009
How can I re-write this function in OCaml so that it allows the elements of the tuple to have different types
let nth i (x,y,z) =
match i with
1->x
|2->y
|3->z
|_->raise (Invalid_argument "nth")
The short answer is that it's not possible. OCaml is strongly and statically typed. A function returns a single type. Since your function returns x, y, and z in different cases, then these must all be the same type.
OCaml types are not like types in the so-called dynamically typed languages. You need to think differently. The benefits are (in my opinion) tremendous.
It can be done, but you need to fulfill the constraint that all values, returned from the function should be members of one type. The easiest solution is:
let nth i (x,y,z) =
match i with
| 1 -> `Fst x
| 2 -> `Snd y
| 3 -> `Thd z
| _ -> invalid_arg "nth tuple"
The solution demonstrates that you need to address all possible cases for the types of your tuple. Otherwise, your program will not be well-formed, and this contradicts with the static typing. The latter guarantees that your program is well-formed for any input, so that it wont fail in a runtime.
A twin solution, using ordinary ADT instead of polymorphic ones, will look something like this:
type ('a,'b,'c) t =
| Fst of 'a
| Snd of 'b
| Thd of 'c
let nth i (x,y,z) =
match i with
| 1 -> Fst x
| 2 -> Snd y
| 3 -> Thd z
| _ -> invalid_arg "nth tuple"
An exotic solution (not very practible, maybe) that uses GADT to form an existential type will look like this:
type t = Dyn : 'a -> t
let nth i (x,y,z) =
match i with
| 1 -> Dyn x
| 2 -> Dyn y
| 3 -> Dyn z
| _ -> invalid_arg "nth tuple"
How can user defined functions (say f) have meaningful printouts when inspected via the REPL using ?for help(f)
For example imagine I write the following funciton
function f(x::Float64, y::Float64)
return 2x - y^2
end
If I load this into a julia session and try help(f) I get the following:
julia> help(f)
f (generic function with 1 method)
What if instead I wanted to see something like
julia> help(f)
f
Compute 2 times x minus y squared
where the description "Compute 2 times x minus y squared" is written somewhere. I am guessing the answer to my question can be determined from the answer to the question "Where is the somewhere the description should be written?"
By way of example, if I wanted to do the same in python, I could define the function and put the description as a docstring:
def f(x, y):
"""
Compute 2 times x minus y squared
"""
return 2 * x - y ** 2
which would make my description immediately available when I type help(f) or f? from IPython.
You can use the #doc macro in Julia versions 0.4 (Oct. 2015) and above.
% julia
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.4.0 (2015-10-08 06:20 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-apple-darwin13.4.0
julia> #doc """
Compute 2 times x minus y squared.
""" ->
function f(x::Float64, y::Float64)
return 2x - y^2
end
f (generic function with 1 method)
julia> #doc f
Compute 2 times x minus y squared.
Edit: As pointed out by #Harrison Grodin, versions 0.5 and above support an abbreviated syntax as well as Markdown, LaTEX, and a few other goodies:
"""
Calculate the left Riemann sum[^1] approximating ``\int_a^b f(x) dx = F(b) - F(a).``
[^1]: Thomas G., Finney R. (1996), Calculus and Analytic Geometry, Addison Wesley, ISBN 0-201-53174-7
"""
function rs(a, b, d, f)
end
There are more details in the documentation.
In Julia v0.5+ (including more recent Julia Versions like 1.2+), you can write a multiline string above the function definition. (No need for #doc anymore.)
julia> """
cube(x)
Compute the cube of `x`, ``x^3``.
# Examples
```jldoctest
julia> cube(2)
8
```
"""
function cube(x)
x^3
end
cube
help?> cube
search: Cdouble isexecutable Ac_mul_B Ac_mul_Bc Ac_mul_B! Ac_mul_Bc! cumsum_kbn
cube(x)
Compute the cube of x, x^3.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> cube(2)
8
For more information on properly formatting your docstrings, see the official Julia Documentation.
In case I have to disassemble a data type as its variable size, can I still use the "match and with, and if the answer is yes you could help me figure out how (I'm a beginner with this language), or do I or use other methods.
the type defined is this :
type 'state formula =
| And of 'state formula list
| Or of 'state formula list
| Literal of bool
| Variable of 'state
from the examples I've seen the "match and with" is used when the structure of the static type was, in my case as I do?
So here's an example which uses match to work with your formula type:
type 'state formula = | And of 'state formula list | Or of 'state formula list | Literal of bool | Variable of 'state
let rec count_vars form = match form with
| And forms
| Or forms -> List.fold_left (+) 0 (List.map count_vars forms)
| Literal _ -> 0
| Variable _ -> 1
let formula = And [ Variable "q0"; Or[ Variable "q1";Variable "q2"]; Variable "q3"]
let vars_in_formula = count_vars formula (* 4 *)
If you want to manipulate the type, you can use patter matching(among other things, but I find this the most elegant). It's essentially syntactical sugar for Match with.
For example:
let identify_formula=function
And(l) -> 0
|Or(l) -> 1
|Literal(b) -> 2
| Variable(v) -> 3;;
For a less trivial example of how to manipulate types:
type l=Cons of int*l
| Nil;;
let rec sum_l=function
Cons(hd,tl)->hd+ sum_l(tl)
| Nil-> 0;;
sum_l(Cons(1,Cons(2,Cons(3,Nil))));; (*r6*)
Maybe you would like a code example to adapt to your needs.
type 'state formula =
| Literal of bool
| And of 'state formula list
| Or of 'state formula list
| Variable of 'state
let rec eval variable_env formula =
match formula with
| Literal b -> b
| Variable v -> variable_env v
| And formulas -> List.for_all (eval variable_env) formulas
| Or formulas -> List.exists (eval variable_env) formulas
(* same as eval, different code *)
let rec eval2 env = function
| Literal b -> b
| Variable v -> env v
| And [] -> true
| And (hd::tl) -> eval env hd && eval2 env (And tl)
| Or [] -> false
| Or (hd::tl) -> eval env hd || eval2 env (Or tl)