How to pretty print matrix to String in Julia? - julia

How to use show to pretty print matrix to String?
It's possible to print it to stdout with show(stdout, "text/plain", rand(3, 3)).
I'm looking for something like str = show("text/plain", rand(3, 3))

For simple conversions usually DelimitedFiles is your best friend.
julia> a = rand(2,3);
julia> using DelimitedFiles
julia> writedlm(stdout, a)
0.7609054249392935 0.5417287267974711 0.9044189728674543
0.8042343804934786 0.8206460267786213 0.43575947315522123
If you want to capture the output use a buffer:
julia> b=IOBuffer();
julia> writedlm(b, a)
julia> s = String(take!(b))
"0.7609054249392935\t0.5417287267974711\t0.9044189728674543\n0.8042343804934786\t0.8206460267786213\t0.43575947315522123\n"
Last but not least, if you want to have a stronger control use CSV - and the pattern is the same - either use stdout or capture the output using a buffer e.g.:
julia> using CSV, Tables
julia> b=IOBuffer();
julia> CSV.write(b, Tables.table(a));
julia> s = String(take!(b))
"Column1,Column2,Column3\n0.7609054249392935,0.5417287267974711,0.9044189728674543\n0.8042343804934786,0.8206460267786213,0.43575947315522123\n"
Even more - if you want to capture the output from display - you can too!
julia> b=IOBuffer();
julia> t = TextDisplay(b);
julia> display(t,a);
julia> s = String(take!(b))
"2×3 Array{Float64,2}:\n 0.760905 0.541729 0.904419\n 0.804234 0.820646 0.435759"

What you were looking for:
b = IOBuffer()
show(b, "text/plain", rand(3, 3))
s = String(take!(b))

Related

How to create a non-standard string literal with parameters in Julia?

I am creating a non-standard string literal with a macro with something like that:
macro R13_str(p)
rotate(13, p)
end
and it works. I can call it as:
R13"abc"
But I would like to declare the macro to work with any integer, like:
R1"abc"
or
R244"abc"
Let's say the function rotate() is:
function rotate(shift_amount::Int64, s::String)
# Ensure the shift is no bigger than the string
shift = shift_amount ≤ length(s) ? shift_amount : shift_amount % length(s)
# Circular shift
return s[end-shift+1:end] * s[1:end-shift]
end
How can I do that? I have checked all the docs, but it's not clear to me.
Can't see how to achieve exactly what is required. But the following might be good enough:
julia> macro R_str(p,flag)
rotate(flag, p)
end
#R_str (macro with 1 method)
julia> R"hello"3
"llohe"
julia> R"abc"1
"cab"
julia> R"abc"244
"cab"
See https://docs.julialang.org/en/v1/manual/metaprogramming/#meta-non-standard-string-literals
Trying to conform to OP call format:
julia> macro rework(expr)
if expr.head != :macrocall return expr ; end
r = String(expr.args[1])
rr = parse(Int, r[3:findfirst('_',r)-1])
:(rotate($rr, $(expr.args[3])))
end
#rework (macro with 1 method)
julia> #rework R13"hello"
"llohe"
This macro could help to read the prepared test cases??
I have found a solution:
for n in 0:244
#eval macro $(Symbol(:R, n, :_str))(s)
rotate($n, s)
end
end
While I believe that using flags is the better approach, with this for loop I can generate all the macros that I need.
Julia> R1"abc"
Julia> R24"acb"
Julia> R56"abc"
simply work.

Why does the Base.match function return a SubString{String} type rather than just String in Julia?

julia> s = "abcdefg"
"abcdefg"
julia> s1 = s[3:4]
"cd"
julia> s2 = match(r"c.", s).match
"cd"
julia> typeof(s)
String
julia> typeof(s1)
String
julia> typeof(s2)
SubString{String}
What functionality does SubString enable? It looks like a container. If so, what other types can it hold? If this is useful, why isn't s1 a SubString?
I found this behavior strange when I had to convert s2 into a pure String to get it into a f(x::String) function. What is the difference between using String(s2) and string(s2) for that conversion?
SubString{String} is just a view of String. s1[3:4] is not a SubString because it is getindex not view function (just like with arrays).
It is SubString{String} to avoid copying of data in the string, see e.g.:
julia> using BenchmarkTools
julia> x = "a"^1_000_000;
julia> #btime $x[1:end];
36.000 μs (1 allocation: 976.69 KiB)
julia> #btime #view $x[1:end];
23.046 ns (0 allocations: 0 bytes)
to note how much difference in allocations and speed it makes
In general you should avoid writing s[3:4] as it is not a safe indexing code (it is only safe if your string is ASCII which you can check with isascii). String indexing in Julia uses byte indices (not character indices)
SubString{String} has String parameter, as there are in general other string types than only String:
julia> using InlineStrings
julia> x = InlineString("abcd")
"abcd"
julia> typeof(x)
String7
julia> y = #view x[1:end]
"abcd"
julia> typeof(y)
SubString{String7}
As it is noted in comment by Antonello - most likely the f function should accept AbstractString and you would not even notice a problem.
All this is explained in https://docs.julialang.org/en/v1/manual/strings/.
If you want something more hands-on check out for example chapter 6 of https://www.manning.com/books/julia-for-data-analysis (I do not want to do too much self promotion, but your question is one of the standard questions users ask and I explained all these topics in this chapter to address them).

Double Broadcasting in Julia for Matrix Vector Addition?

Newbie Julia question here. Given two arrays,
W = [randn(3,2), randn(3,2)]
b = [randn(3), randn(3)]
I would like to do a "nested broadcast" along the lines of,
W .+ b = [W[1].+b[1], W[2].+b[2]]
So far the best I've been able to come up with is,
[Wi.+bi (Wi,bi) for zip(W,b)]
Coming from a Python background this feels sacrilegious. Is there a better way to do this in Julia?
You could do something like the following:
julia> W = [randn(3,2), randn(3,2)]
2-element Array{Array{Float64,2},1}:
[0.39179718902868116 -0.5387622679356612; -0.594274465053327 0.018804631512093436; -2.273706742420988 -0.4638617400026042]
[0.3249960563405678 -0.4877554417492699; 0.5036437919340767 1.3172770503034696; 0.03501532820428975 -0.2675024677340758]
julia> b = [randn(3), randn(3)]
2-element Array{Array{Float64,1},1}:
[1.2571527266220441, 0.21599608118129476, 0.21498843153804936]
[-0.528960345932853, 0.5610435189953311, -0.8636370930615718]
# A helper function which broadcasts once
julia> s_(Wi, bi) = Wi .+ bi
s_ (generic function with 1 method)
# Broadcast the helper function
julia> s_.(W, b)
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
As mentioned in comments, you can use one of the available user-definable infix operators to name the helper function, which allows for a nicer syntax (the particular symbol used below can be obtained by typing \oplus then Tab):
julia> ⊕(x, y) = x .+ y
⊕ (generic function with 1 method)
julia> W .⊕ b
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
Or - again as mentioned in comments - if you don't feel like explicitly declaring a helper function:
julia> ((Wi, bi)->Wi.+bi).(W, b)
2-element Array{Array{Float64,2},1}:
[1.6489499156507252 0.718390458686383; -0.3782783838720323 0.2348007126933882; -2.0587183108829388 -0.24887330846455485]
[-0.20396428959228524 -1.016715787682123; 1.0646873109294077 1.8783205692988008; -0.828621764857282 -1.1311395607956476]
(I personally have more difficulty reading that last version, but YMMV)
When you want to broadcast broadcast, then broadcast broadcast:
julia> broadcast.(+, W, b)
2-element Array{Array{Float64,2},1}:
[-0.7364111670769904 0.010994354421031916; -0.9010128415786036 0.22868802910609998; 1.2030371118617933 0.21305414210853912]
[0.19183885867446926 0.5362077496502086; 1.5909421118115665 0.1235808501390212; 1.5190965380769597 0.1883638848487652]
julia> [W[1].+b[1], W[2].+b[2]]
2-element Array{Array{Float64,2},1}:
[-0.7364111670769904 0.010994354421031916; -0.9010128415786036 0.22868802910609998; 1.2030371118617933 0.21305414210853912]
[0.19183885867446926 0.5362077496502086; 1.5909421118115665 0.1235808501390212; 1.5190965380769597 0.1883638848487652]

Is there a function for printing the REPL content to a file in Julia language?

I already have output some content in the REPL. Is there any function to print all this content to a file?
If those outputs have already been printed in the REPL, I guess the only way to save them to a file is copy-pasting manually. But if you would like to save the REPL output history for future use, one way is to overload display:
shell> touch repl_history.txt
julia> using REPL
julia> function REPL.display(d::REPL.REPLDisplay, mime::MIME"text/plain", x)
io = REPL.outstream(d.repl)
get(io, :color, false) && write(io, REPL.answer_color(d.repl))
if isdefined(d.repl, :options) && isdefined(d.repl.options, :iocontext)
# this can override the :limit property set initially
io = foldl(IOContext, d.repl.options.iocontext,
init=IOContext(io, :limit => true, :module => Main))
end
show(io, mime, x)
println(io)
open("repl_history.txt", "a") do f
show(f, mime, x)
println(f)
end
nothing
end
then, let's print something random in the REPL:
julia> rand(10)
10-element Array{Float64,1}:
0.37537591915616497
0.9478991508737484
0.32628512501942475
0.8888960925262224
0.9967927432272801
0.4910769590205608
0.7624517049991089
0.26310423494973545
0.5117608425961135
0.0762255311602309
help?> gcd
search: gcd gcdx significand
gcd(x,y)
Greatest common (positive) divisor (or zero if x and y are both zero).
Examples
≡≡≡≡≡≡≡≡≡≡
julia> gcd(6,9)
3
julia> gcd(6,-9)
3
And here is what the file content looks like:
shell> cat repl_history.txt
10-element Array{Float64,1}:
0.37537591915616497
0.9478991508737484
0.32628512501942475
0.8888960925262224
0.9967927432272801
0.4910769590205608
0.7624517049991089
0.26310423494973545
0.5117608425961135
0.0762255311602309
gcd(x,y)
Greatest common (positive) divisor (or zero if x and y are both zero).
Examples
≡≡≡≡≡≡≡≡≡≡
julia> gcd(6,9)
3
julia> gcd(6,-9)
3
If there is no need to work with REPL interactively, simply use julia script.jl > output.txt might also do the trick.
What you've printed isn't saved anywhere, so no, there's no way to do that. It may be that there's something easy to do but without more details it's impossible to way really.
If you want to save variables to file, you can you JLD2 package. Then you can save each variable as below:
using JLD2, FileIO
hello = "world"
foo = :bar
#save "example.jld2" hello foo

Assign vector components to different variables in Julia

I want to assign the result of an operation to a concatenation of variables in Julia. Something similar to this (although this doesn't work):
a = zeros(5)
b = zeros(5)
a, b .= rand(10)
Is it possible? Thank you.
You are looking for "vector view concatenation". The idea here is to use SubArrays to build an Array that is actually a view into two arrays. Julia does not support this out of the box. The Julia package ChainedVectors.jl was built for this, but it is heavily outdated and only works with Julia <= 0.4.
Not everything is lost. You have two alternatives:
Use CatViews.jl
As pointed out in the comments, CatViews.jl is like ChainedVectors.jl, but works with Julia 0.6 and 0.7:
Pkg.add("CatViews")
using CatViews
a = zeros(2)
b = zeros(2)
CatView(a, b) .= rand(4)
Build your own solution
With a little work, we can get as good as
a = zeros(2)
b = zeros(2)
MyView(a, b) .= rand(4)
Julia allows you to build your own view-concatenation type. The effort required to build it scales proportional to how general you want it to be. Here is a first attempt that works with vectors:
julia> # Create a type for a view into two vectors.
julia> type MyView{T} <: AbstractVector{T}
a::Vector{T}
b:: Vector{T}
end
julia> import Base: size, getindex, setindex!
julia> # Define methods to make MyView behave properly.
julia> size(c::MyView) = size(c.a) .+ size(c.b)
julia> getindex(c::MyView, i::Int) = i <= length(c.a) ? getindex(a, i) : getindex(b, i-length(a))
julia> setindex!(c::MyView, val, i::CartesianIndex) = i[1] <= length(c.a) ? setindex!(c.a, val, i[1]) : setindex!(c.b, val, i[1]-length(a))
julia> setindex!(c::MyView, val, i::Int) = i <= length(c.a) ? setindex!(c.a, val, i) : setindex!(c.b, val, i-length(a))
julia> # Test MyView. Define two arrays and put them
julia> # into a single view.
julia> a = rand(2)
2-element Array{Float64,1}:
0.701867
0.543514
julia> b = rand(2)
2-element Array{Float64,1}:
0.00355893
0.405809
julia> MyView(a, b) .= rand(4)
4-element MyView{Float64}:
0.922896
0.969057
0.586866
0.457117
julia> # Hooray, it worked! As we see below,
julia> # the individual arrays were updated.
julia> a
2-element Array{Float64,1}:
0.922896
0.969057
julia> b
2-element Array{Float64,1}:
0.586866
0.457117
This?
a .= x[1:5]
b .= x[6:end]
You must tell Julia somehow where to split the vector.

Resources