I am trying to compute the quadratic formula and place the results within an array before printing out the result:
function f(a, b, c)
r1 = (-b+sqrt(complex(b^2-4*a*c)))/2.0*a
r2 = (-b-sqrt(complex(b^2-4*a*c)))/2.0*a
x = [r1][r2]
println(x)
end
However I get the following error:
f(1, 2, 3)
ArgumentError: invalid index: -1.0 - 1.4142135623730951im of type ComplexF64
This code could look like this:
function f(a, b, c)
Δsqrt = √(b^2-4a*c+0im)
r1 = (-b+Δsqrt)/2a
r2 = (-b-Δsqrt)/2a
[r1, r2] # or use tuple (r1, r2)
end
And some exaples:
julia> f(1,0,1)
2-element Vector{ComplexF64}:
0.0 + 1.0im
0.0 - 1.0im
julia> f(1,0,-1)
2-element Vector{ComplexF64}:
1.0 + 0.0im
-1.0 - 0.0im
Related
How do I use both Julia's dot notation to do elementwise operations AND ensure that the result is saved in an already existing array?
function myfun(x, y)
return x + y
end
a = myfun(1, 2) # Results in a == 3
a = myfun.([1 2], [3; 4]) # Results in a == [4 5; 5 6]
function myfun!(x, y, out)
out .= x + y
end
a = zeros(2, 2)
myfun!.([1 2], [3; 4], a) # Results in a DimensionMismatch error
Also, does #. a = myfun([1 2], [3; 4]) write the result to a in the same way as I am trying to achieve with myfun!()? That is, does that line write the result directly to a without saving storing the result anywhere else first?
Your code should be:
julia> function myfun!(x, y, out)
out .= x .+ y
end
myfun! (generic function with 1 method)
julia> myfun!([1 2], [3; 4], a)
2×2 Matrix{Float64}:
4.0 5.0
5.0 6.0
julia> a
2×2 Matrix{Float64}:
4.0 5.0
5.0 6.0
As for #. a = myfun([1 2], [3; 4]) - the answer is yes, it does not create temporary arrays and operates in-place.
This isn't commonly required, and there are usually better ways to achieve this, but it's possible to broadcast on an output argument by using Reference values that point inside the output array.
julia> a = zeros(2, 2)
2×2 Matrix{Float64}:
0.0 0.0
0.0 0.0
julia> function myfun!(out, x, y)
out[] = x + y
end
myfun! (generic function with 1 method)
julia> myfun!.((Ref(a, i) for i in LinearIndices(a)), [1 2], [3; 4])
2×2 Matrix{Int64}:
4 5
5 6
julia> a
2×2 Matrix{Float64}:
4.0 5.0
5.0 6.0
Edit: Changed out to be the first parameter as per the Style guide - thanks to #phipsgabler for the reminder.
when I want to extract a real part of g(x) and integrate a new function g1(x), the result b contains a Vector {Float 64} rather than just a number. How to get its integrated result?
Here is the code
g(x) = (exp.(-x).^2).*exp.(1im*x)
R_initial=real(g(x));
g1(x)= R_initial
b = quadgk(g1,0.6,0.7)
c = b[1]
Just do the following:
julia> g(x) = real((exp(-x)^2)*exp(1im*x))
g (generic function with 1 method)
julia> quadgk(g,0.6,0.7)
(0.021750435727577098, 3.469446951953614e-18)
In your code:
R_initial=real(g(x))
takes some global value of x that you probably have and R_initial is bound to some value. So you get something like:
julia> R_initial = [1.0, 2.0]
2-element Vector{Float64}:
1.0
2.0
julia> g1(x) = R_initial
g1 (generic function with 1 method)
julia> quadgk(g1,0.6,0.7)
([0.09999999999999998, 0.19999999999999996], 0.0)
which produces a vector in the first element as the input is multi-dimensional. Note that g1 is just a constant function.
I have a complex matrix (i.e. Array{Complex{Float64},2}) in julia that I would like to upsample in one dimension.
My equivalent python code is:
data_package['time_series'] = sp.signal.resample(data_package['time_series'] .astype('complex64'), data_package['time_series'].shape[1]*upsample_factor, axis=1)
A resample() function can be found in DSP.jl. But it only works on Vectors, so one has to apply it manually along the desired dimension. One possible way looks like this (resampling along the second dimension, with a new rate of 2):
julia> using DSP
julia> test = reshape([1.0im, 2.0im, 3.0im, 4., 5., 6.], 3, 2)
3×2 Matrix{ComplexF64}:
0.0+1.0im 4.0+0.0im
0.0+2.0im 5.0+0.0im
0.0+3.0im 6.0+0.0im
julia> newRate = 2
2
julia> up = [resample(test[:, i], newRate) for i in 1:size(test, 2)] # gives a vector of vectors
2-element Vector{Vector{ComplexF64}}:
[0.0 + 0.9999042566881922im, 0.0 + 1.2801955476665785im, 0.0 + 1.9998085133763843im, 0.0 + 2.968204475861045im, 0.0 + 2.9997127700645763im]
[3.9996170267527686 + 0.0im, 4.466495565312296 + 0.0im, 4.999521283440961 + 0.0im, 6.154504493506763 + 0.0im, 5.9994255401291525 + 0.0im]
julia> cat(up..., dims = 2) # fuse to matrix
5×2 Matrix{ComplexF64}:
0.0+0.999904im 3.99962+0.0im
0.0+1.2802im 4.4665+0.0im
0.0+1.99981im 4.99952+0.0im
0.0+2.9682im 6.1545+0.0im
0.0+2.99971im 5.99943+0.0im
Please consider the package FFTResampling.jl
The method is based on the FFT, assuming periodic and band-limited input.
I am trying to use a transpose operator over a vector in order to perform am element-wise addition.
For example, I want to add a column vector a = [a1;a2;a3] to a row vector b = [b1,b2] I should get matrix
M = a+b = [a1+b1, a1+b2; a2+b1, a2+b2; a3+b1, a3+b2].
In MATLAB it is equivalent (if both vectors are row vectors) M = a.'+b
I am trying to get the same in Julia but here is the problem, there is no .' operator in Julia starting from 1.0 version. There is the transpose operator which does not work in broadcasting mode. The adjoint operator is not Valid for me because I work with complex numbers.
a = Vector{ComplexF64}([1+3im,2])
b = Vector{ComplexF64}([0,0,0])
Z = zeros(ComplexF64,3,2)
G = zeros(ComplexF64,3,2)
#. Z = b + a' # Works but takes the complex conjugate
#. Z = b + transpose(a) # DOES NOT WORK!!!! The error is " DimensionMismatch("array could not be broadcast to match destination") "
Z = b .+ transpose(a) # Works but not efficient
#. Z = b + conj(a')
The third case Z = b .+ transpose(a) is not efficient because it makes 2 loops first one for addition b .+ transpose(a), than it runs the second loop one for the assignment of b .+ transpose(a) to Z. While the other 3 cases do it within one loop.
So which is the fastest way?
And why transpose doesn't within Broadcasting?
Thank you in advance
For Hermitian You can just type:
a' .+ b
Example
julia> a = ComplexF64.([1+3im,2])
2-element Array{Complex{Float64},1}:
1.0 + 3.0im
2.0 + 0.0im
julia> b = ComplexF64.([10,20,30])
3-element Array{Complex{Float64},1}:
10.0 + 0.0im
20.0 + 0.0im
30.0 + 0.0im
julia> a' .+ b
3×2 Array{Complex{Float64},2}:
11.0-3.0im 12.0+0.0im
21.0-3.0im 22.0+0.0im
31.0-3.0im 32.0+0.0im
If you want to have just transposition you could define your own unary operator (perhaps from the list of unused unary operators):
¬(a) = permutedims(a)
Now you could do
julia> ¬a
1×2 Matrix{ComplexF64}:
1.0+3.0im 2.0+0.0im
I have an empty matrix initially:
m = Matrix(0, 3)
and a row that I want to add:
v = [2,3]
I try to do this:
[m v]
But I get an error
ERROR: ArgumentError: number of rows of each array must match
What's the proper way to do this?
That is because your matrix sizes don't match. Specifically v does not contain enough columns to match m. And its transposed
So this doesnt work
m = Matrix(0, 3)
v = [2,3]
m = cat(1, m, v) # or a = [m; v]
>> ERROR: DimensionMismatch("mismatch in dimension 2 (expected 3 got 1)")
whereas this does
m = Matrix(0, 3)
v = [2 3 4]
m = cat(1, m, v) # or m = [m; v]
>> 1x3 Array{Any,2}:
>> 2 3 4
and if you run it again it creates another row
m = cat(1, m, v) # or m = [m; v]
>> 2x3 Array{Any,2}:
>> 2 3 4
>> 2 3 4
Use the vcat (concatenate vertically) function:
help?> vcat
search: vcat hvcat VecOrMat DenseVecOrMat StridedVecOrMat AbstractVecOrMat levicivita is_valid_char #vectorize_2arg
vcat(A...)
Concatenate along dimension 1
Notice you have to transpose the vector v, ie. v', else you get a DimensionMismatch error:
julia> v = zeros(3)
3-element Array{Float64,1}:
0.0
0.0
0.0
julia> m = ones(3, 3)
3x3 Array{Float64,2}:
1.0 1.0 1.0
1.0 1.0 1.0
1.0 1.0 1.0
julia> vcat(m, v') # '
4x3 Array{Float64,2}:
1.0 1.0 1.0
1.0 1.0 1.0
1.0 1.0 1.0
0.0 0.0 0.0
julia> v' # '
1x3 Array{Float64,2}:
0.0 0.0 0.0
julia> vcat(m, v)
ERROR: DimensionMismatch("mismatch in dimension 2 (expected 3 got 1)")
in cat_t at abstractarray.jl:850
in vcat at abstractarray.jl:887
Note: the comments; # ' are there just to make syntax highlighting work well.
Isn't that Matrix creates a two-dimensional array in Julia? If you try with m =[0, 3], which creates a one-dimensional Vector for you, you can append it by [m; v].
I think using [m v] is create a two-dimensional array as well, from the Julia Document