When I substitute symbolic variables x1, x2 into a function, the sum notation "+=" (in the function definition) does not allow them because it only accepts reals. Therefore it spits out a TypeError. I need to substitute symbolic variables into the function. Is there any workaround?
---update:---
I have tried replacing += with sum() without breaking my function, something like M[i,j] = sum([L[i]/(L[i]-L[k]) for k in range(n) if i != k]). When substituting x1 x2, it spits out the same error: TypeError: unable to convert x1/(x1 - x2) to a rational
Here's my attempt:
x1,x2 = var('x1 x2')
A2 = Afunction(2, [x1,x2])
#Afunction takes an integer n and a list as the inputs, the output is a n by n matrix
Related
I have two 1-D arrays in which I would like to calculate the approximate cumulative integral of 1 array with respect to the scalar spacing specified by the 2nd array. MATLAB has a function called cumtrapz that handles this scenario. Is there something similar that I can try within Julia to accomplish the same thing?
The expected result is another 1-D array with the integral calculated for each element.
There is a numerical integration package for Julia (see the link) that defines cumul_integrate(X, Y) and uses the trapezoidal rule by default.
If this package didn't exist, though, you could easily write the function yourself and have a very efficient implementation out of the box because the loop does not come with a performance penalty.
Edit: Added an #assert to check matching vector dimensions and fixed a typo.
function cumtrapz(X::T, Y::T) where {T <: AbstractVector}
# Check matching vector length
#assert length(X) == length(Y)
# Initialize Output
out = similar(X)
out[1] = 0
# Iterate over arrays
for i in 2:length(X)
out[i] = out[i-1] + 0.5*(X[i] - X[i-1])*(Y[i] + Y[i-1])
end
# Return output
out
end
I came across this fantastic function called
within {base}
I use it more often now than the much hyped
mutate {dplyr}
My question is, why is within() having such a peculiar format with assignment operators used <- instead of the usual = for args; How is it different from mutate other than what is given in this fantastic article I found. I am interested to know the underlying mechanism.
Article of Bob Munchen - 2013
The function within takes an expression as second argument. That expression is essentially a codeblock, best contained within curly brackets {}.
In this codeblock, you can assign new variables, change values and the likes. The variables can be used in the codeblock as objects.
mutate on the other hand takes a set of arguments for the mutation. These arguments have to be named after the variable that should be created, and get the value for that variable as the value.
So :
mutate(iris, ratio = Sepal.Length/Petal.Length)
# and
within(iris, {ratio = Sepal.Length/Petal.Length})
give the same result. The problem starts when you remove the curly brackets:
> within(iris, ratio = Sepal.Length/Petal.Length)
Error in eval(substitute(expr), e) : argument is missing, with no default
The curly brackets enclosed an expression (piece of code), and hence within() worked correctly. If you don't use the {}, then R semantics reads that last command as "call the function within with iris as first argument and a second argument called ratio set to Sepal.Length/Petal.Length". And as the function within() doesn't have an argument ratio, that one is ignored. Instead, within looks for the expression that should be the second argument. But it can't find that one, so that explains the error.
So there's little peculiar about it. Both functions just have different arguments. All the rest is pretty much how R deals with arguments.
Args of within are not assigned with <- but with the usual =.
Let's see the first example in your link:
mydata.new <- within(mydata, {
+ x2 <- x ^ 2
+ x3 <- x2 + 100
+ } )
Here,
{
x2 <- x ^ 2
x3 <- x2 + 100
}
is just an argument of the function (an R expression). Nor x2 nor x3 are arguments to within. The function could have been called in that way instead to make it clearer:
mydata.new <- within(data = mydata, expr = {
x2 <- x ^ 2
x3 <- x2 + 100
})
I've been using the following function to take in user input for something I'm writing in Julia:
function input(prompt::AbstractString = "")
println(prompt * " ")
chomp(readline())
end
In my particular case, the input that I'm taking in is in the form of equations such as "y = x^2". After the input() function passes it to me as an ASCIIString, I then use the parse() function to convert it to an Expression:
:(y = x^2)
As an Expression, I can use the .args attribute to do things like counting the number of variables and returning the unique variables, all of which has worked fine. Now, I need to be able to evaluate the right side of the expression as the Function f(x) = x^2. To do so, I began writing the following function (which has some pretty major flaws):
function evalExpression()
L = [1,2,3,4]
equation = parse(input("Enter an equation"))
f = equation.args[2].args[2]
for i in L
x = i
value = eval(f)
println(value)
end
end
This function has two problems that I haven't been able to resolve. The first is that it gives me an UndefVarError for x when I try to run it right now; that's more or less expected. The second is that unless I knew that the user would input a function of only x, I would have no way of figuring out what the variables I needed to assign were. I wrote a recursive function that can take in an expression and return all its variables in the form of [:x, :y, etc.], but I cannot assign :x to a number to evaluate the function--I need to assign it just to x, and I cannot figure out how to access that. Is there anything that I can use to access the variables I need? Or a different approach I could take?
Thank you!
When I run the following:
function evalExpression()
L = [1,2,3,4]
equation = parse(input("Enter an equation"))
global x
for i in L
x = i
f = equation.args[2].args[2]
value = eval(f)
println(value)
end
end
and then putting y = x*x I get
evalExpression()
Enter an equation
y = x*x
1
2
3
4
What is missing, at least for x as a variable, is declaring it globally. When you eval parsed statements, these parsed statements only access global variables
So what you probably need to do after you've invented your recursive function to correctly fetch variables, is to create them globally. Maybe
eval(parse("$variable = 0"))
will do
The Question: I was hoping to find a function like findInterval in R which gives inputs a scalar and a vector representing interval starting points and returns the index of what interval the scalar falls in. For instance in R:
findInterval(x = 2.6, vec = c(1.1,2.1,3.1,4.1))
#[1] 2
In this exchange someone gave a function that does this functionality in Julia (See next section). Apparently the base indexin function does this task though. I was wondering how to get indexin function (or another base function) to do this. I know Julia loops are fast and I could write a function but I would rather not do that if there is an inbuilt function and this should be a common problem.
When I try the indexin function with the same numbers I used in R above I get:
indexin([2.6], [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 0
Which just indicates that 2.6 is not in the vector as it (as I understand) is looking to match values rather than placing a scaler in an interval.
Function from above referenced link (with my changes to input\output datatypes)
function findInterval(x::Float64,vec::Array{Float64})
out = zeros(Int,length(x))
vec = unique(vec)
sort!(vec)
for j in 1:length(x)
if x[j] < vec[1]
out[1] = 0
elseif x[j] > vec[end]
out[end] = 0
else
out[j] = searchsortedfirst(vec,x[j])-1
end
end
return out
end
Which works as intended:
findInterval(2.6, [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 2
Related Questions from SO: Other questions on SO look for finding the index of exact matches between an input value and a vector:
Julia version of R's Match?
Find first index of an item in an array in Julia
Vectorized "in" function in julia?
If your input vector is always sorted, then searchsortedlast will do what you want, e.g.
vec = [1.1, 2.1, 3.1, 4.1]
x = 2.6
searchsortedlast(vec, x)
However, note that searchsortedlast will return 0 if x < vec[1], and will return length(vec) if x > vec[end]. So you might want to write your own custom behaviour that checks for these outcomes, e.g. if you want to always return 0 if x is not in any of the intervals in vec, you could write:
function find_interval(vec, x)
i = searchsortedlast(vec, x)
i == length(vec) && (i = 0)
return(i)
end
Also, if you work a lot with sorted vectors, you might be interested in a package I've written for sorted vectors in Julia, but have never gotten around to adding to METADATA. The source of SortedVectors package is here.
New to Julia. Following this blog to do Neural Network:
http://blog.yhathq.com/posts/julia-neural-networks.html
I am confused about data types and error messages in Julia. This is my code (again, following the blog post on Neural Network):
# read in df to train
train_df = readtable("data/winequality-red.csv", separator=';')
# create train and test data splits
y = train_df[:quality]
x = train_df[:, 1:11] # matrix of all except quality
# vector() and matrix() from blog post
n = length(y)
is_train = shuffle([1:n] .> floor(n * .25))
x_train,x_test = x[is_train,:],x[!is_train,:]
y_train,y_test = y[is_train],y[!is_train]
type StandardScalar
mean::Vector{Float64}
std::Vector{Float64}
end
# initialize empty scalar
function StandardScalar()
StandardScalar(Array(Float64, 0), Array(Float64, 0))
end
# compute mean and std of each col
function fit_std_scalar!(std_scalar::StandardScalar, x::Matrix{Float64})
n_rows, n_cols = size(x_test)
std_scalar.std = zeros(n_cols)
std_scalar.mean = zeros(n_cols)
for i = 1:n_cols
std_scalar.mean[i] = mean(x[:,i])
std_scalar.std[i] = std(x[:,i])
end
end
# further vectorize the transformation
function transform(std_scalar::StandardScalar, x::Matrix{Float64})
# element wise subtraction of mean and division of std
(x .- std_scalar.mean') ./ std_scalar.std'
end
# fit and transform
function fit_transform!(std_scalar::StandardScalar, x::Matrix{Float64})
fit_std_scalar!(std_scalar, x)
transform(std_scalar, x)
end
# fit scalar on training data and then transform the test
std_scalar = StandardScalar()
n_rows, n_cols = size(x_test)
# cols before scaling
println("Col means before scaling: ")
for i = 1:n_cols
# C printf function
#printf("%0.3f ", (mean(x_test[:, i])))
end
I am getting the error:
'.-' has no method matching .-(::DataFrame, ::Array{Float64,2}) in fit_transform! ...
For this code:
x_train = fit_transform!(std_scalar, x_train)
x_test = transform(std_scalar, x_test)
# after transforming
println("\n Col means after scaling:")
for i = 1:n_cols
#printf("%0.3f ", (mean(x_test[:,i])))
end
I am new to Julia and am just not understanding what the issue is. Vector() and Matrix() do not work from the blog post. I assume that was from an older version of DataFrame.
What I think my issue is: these functions are taking in ::Matrix{Float64} and I am passing in the DataFrame. I assume that deprecated (?) Matrix() would have fixed this? Not sure. How do I analyze this error and pass these functions the correct types (if that is the problem here)?
Thank you!
The error message says that you're attempting an element-wise subtraction, .-, between a DataFrame and an Array but that operation has no definition for those types. A silly example of this sort of situation:
julia> "a" .- [1, 2, 3]
ERROR: `.-` has no method matching .-(::ASCIIString, ::Array{Int64,1})
My guess is that if you add
println(typeof(x_train))
in front of
x_train = fit_transform!(std_scalar, x_train)
that you'll be told that it's a DataFrame rather than an array that you're trying to work with. I'm not experienced with the DataFrame library but may be able to dig up the conversion tomorrow sometime. This is all I have time for just now.
Added comments after obtaining data file
I retrieved winequality-red.csv and worked with its DataFrame
julia> VERSION
v"0.3.5"
julia> using DataFrames
julia> train_df = readtable("data/winequality-red.csv", separator=';')
julia> y = train_df[:quality]
1599-element DataArray{Int64,1}:
julia> x = train_df[:, 1:11]
1599x11 DataFrame
julia> typeof(x)
DataFrame (constructor with 22 methods)
x and y are at this point array-like objects. The blog post apparently uses vector and matrix to convert these to true arrays, but these functions are unfamiliar to me. As IainDunning points out in his answer (I'd like to cite this properly but haven't puzzled that out yet), this conversion is now done via array. Perhaps this is what you need to do:
julia> y = array(train_df[:quality])
1599-element Array{Int64,1}:
julia> x = array(train_df[:, 1:11])
1599x11 Array{Float64,2}:
I've not followed through with an analysis of all of the other code, so this is a hint at the answer rather than a fully fleshed out and tested solution to your problem. Please let me know how this it works out if you give it a try.
I'm accustomed to seeing and using Array{Float64,1} and Array{Float64,2} rather than Vector{Float64} and Matrix{Float64}. Possibly the vector and matrix synonyms for specific types of arrays is deprecated.
I believe vector(...) and matrix(...) were both replaced with just array(...), but I can't find an issue number to correspond with that change.