I would like to log plot a function in Julia.
using Plots
x = 1:100
plot(x.^2, xaxis=:log)
I used the same logic as the working code from above but I got following error:
My guess is that I need to "transform" the function into a unit range (if that makes any sense). However, I am not sure how to do that.
using Plots
function test(a)
alpha = 1
for i in 1:a
alpha += 1
end
return alpha
end
a = 1:100
plot(test(a), xaxis=:log)
MethodError: no method matching (::Colon)(::Int64, ::UnitRange{Int64})
You need to broadcast test like this:
plot(test.(a), xaxis=:log)
(note a . after test)
Alternatively plot is smart enough to know how to plot a function just like this:
plot(test, 1, 100, xaxis=:log)
See here for more examples.
Related
In Julia 1.0.5, I have a function f(x::Vector{<:Real}), defined as
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
The signature is like this, because I would like to use it with the ForwardDiff package, and it works with it just fine. I give the function to ForwardDiff.gradient, and everything works like a charm.
However, I would also like to do some visualizations with PyPlot, using this same function f. Namely, I would like to draw its contour with contourf. For this purpose, I have constructed two vectors X::Vector{<:Real} and Y::Vector{<:Real}, and would like to call the same function f with them to produce the contour.
However, making the call f.([X, Y]) is not broadcasting the vectors as I would like, as I get the error
LoadError: MethodError: no method matching (::getfield(Main, Symbol("#f#1044")))(::Int64)
Closest candidates are:
f(!Matched::Array{#s25,1} where #s25<:Real)
This of course prevents me from using the contourf function, as it needs the values of f on a 2D-grid.
Do I need to define an entirely different f(x::Vector{<:Real}, y::Vector{<:Real}) to be able to plot the contour as I would like, or is there an alternative where I can avoid this?
this problem can be resolved by the power of multiple dispatch:
f(x::Vector{<:Real}) = (x[1] - 2)^2 + ( x[2] - 1 )^2
f(x::Real,y::Real) = f([x,y])
nx = 10
ny = 20
X = rand(nx) #mesh of x points
Y = rand(ny) #mesh of y points
Z = f.(transpose(X),Y) #nx x ny matrix
for the two argument gradient:
two_point_gradient(f,x,y) = ForwardDiff.gradient(f,[x,y])
G = two_point_gradient.(f,transpose(X),Y) #returns a vector of gradients, where G[i..] = gradient(f,X[i..],Y[i...])
I need to solve this differential equation using Runge-Kytta 4(5) on Scilab:
The initial conditions are above. The interval and the h-step are:
I don't need to implement Runge-Kutta. I just need to solve this and plot the result on the plane:
I tried to follow these instructions on the official "Scilab Help":
https://x-engineer.org/graduate-engineering/programming-languages/scilab/solve-second-order-ordinary-differential-equation-ode-scilab/
The suggested code is:
// Import the diagram and set the ending time
loadScicos();
loadXcosLibs();
importXcosDiagram("SCI/modules/xcos/examples/solvers/ODE_Example.zcos");
scs_m.props.tf = 5000;
// Select the solver Runge-Kutta and set the precision
scs_m.props.tol(6) = 6;
scs_m.props.tol(7) = 10^-2;
// Start the timer, launch the simulation and display time
tic();
try xcos_simulate(scs_m, 4); catch disp(lasterror()); end
t = toc();
disp(t, "Time for Runge-Kutta:");
However, it is not clear for me how I can change this for the specific differential equation that I showed above. I have a very basic knowledge of Scilab.
The final plot should be something like the picture bellow, an ellipse:
Just to provide some mathematical context, this is the differential equation that describes the pendulum problem.
Could someone help me, please?
=========
UPDATE
Based on #luizpauloml comments, I am updating this post.
I need to convert the second-order ODE into a system of first-order ODEs and then I need to write a function to represent such system.
So, I know how to do this on pen and paper. Hence, using z as a variable:
OK, but how do I write a normal script?
The Xcos is quite disposable. I only kept it because I was trying to mimic the example on the official Scilab page.
To solve this, you need to use ode(), which can employ many methods, Runge-Kutta included. First, you need to define a function to represent the system of ODEs, and Step 1 in the link you provided shows you what to do:
function z = f(t,y)
//f(t,z) represents the sysmte of ODEs:
// -the first argument should always be the independe variable
// -the second argument should always be the dependent variables
// -it may have more than two arguments
// -y is a vector 2x1: y(1) = theta, y(2) = theta'
// -z is a vector 2x1: z(1) = z , z(2) = z'
z(1) = y(2) //first equation: z = theta'
z(2) = 10*sin(y(1)) //second equation: z' = 10*sin(theta)
endfunction
Notice that even if t (the independent variable) does not explicitly appear in your system of ODEs, it still needs to be an argument of f(). Now you just use ode(), setting the flag 'rk' or 'rkf' to use either one of the available Runge-Kutta methods:
ts = linspace(0,3,200);
theta0 = %pi/4;
dtheta0 = 0;
y0 = [theta0; dtheta0];
t0 = 0;
thetas = ode('rk',y0, t0, ts, f); //the output have the same order
//as the argument `y` of f()
scf(1); clf();
plot2d(thetas(2,:),thetas(1,:),-5);
xtitle('Phase portrait', 'theta''(t)','theta(t)');
xgrid();
The output:
Unlike Matlab, Octave Symbolic has no piecewise function. Is there a work around? I would like to do something like this:
syms x
y = piecewise(x0, 1)
Relatedly, how does one get pieces of a piecewise function? I ran the following:
>> int (exp(-a*x), x, 0, t)
And got the following correct answer displayed and stored in a variable:
t for a = 0
-a*t
1 e
- - ----- otherwise
a a
But now I would like to access the "otherwise" part of the answer so I can factor it. How do I do that?
(Yes, I can factor it in my head, but I am practicing for when more complicated expressions come along. I am also only really looking for an approach using symbolic expressions -- even though in any single case numerics may work fine, I want to understand the symbolic approach.)
Thanks!
Matlab's piecewise function seems to be fairly new (introduced in 2016b), but it basically just looks like a glorified ternary operator. Unfortunately I don't have 2016 to check if it performs any checks on the inputs or not, but in general you can recreate a 'ternary' operator in octave by indexing into a cell using logical indexing. E.g.
{#() return_A(), #() return_B(), #() return_default()}([test1, test2, true]){1}()
Explanation:
Step 1: You put all the values of interest in a cell array. Wrap them in function handles if you want to prevent them being evaluated at the time of parsing (e.g. if you wanted the output of the ternary operator to be to produce an error)
Step 2: Index this cell array using logical indexing, where at each index you perform a logical test
Step 3: If you need a 'default' case, use a 'true' test for the last element.
Step 4: From the cell (sub)array that results from above, select the first element and 'run' the resulting function handle. Selecting the first element has the effect that if more than one tests succeed, you only pick the first result; given the 'default' test will always succeed, this also makes sure that this is not picked unless it's the first and only test that succeeds (which it does so by default).
Here are the above steps implemented into a function (appropriate sanity checks omitted here for brevity), following the same syntax as matlab's piecewise:
function Out = piecewise (varargin)
Conditions = varargin(1:2:end); % Select all 'odd' inputs
Values = varargin(2:2:end); % Select all 'even' inputs
N = length (Conditions);
if length (Values) ~= N % 'default' case has been provided
Values{end+1} = Conditions{end}; % move default return-value to 'Values'
Conditions{end} = true; % replace final (ie. default) test with true
end
% Wrap return-values into function-handles
ValFuncs = cell (1, N);
for n = 1 : N; ValFuncs{n} = #() Values{n}; end
% Grab funhandle for first successful test and call it to return its value
Out = ValFuncs([Conditions{:}]){1}();
end
Example use:
>> syms x t;
>> F = #(a) piecewise(a == 0, t, (1/a)*exp(-a*t)/a);
>> F(0)
ans = (sym) t
>> F(3)
ans = (sym)
-3⋅t
ℯ
─────
9
I am making a little game where when events happen, rectangles get spawned at a random x and y point and I am having some trouble implementing functions into this. Here is some basic code:
xran = random.randint(5, 485)
yran = random.randint(5, 485)
xran1 = random.randint(5, 450)
yran1 = random.randint(5, 400)
def allRand():
#This REGENERATES those randoms making it 'spawn' in a new location.
xran = random.randint(0, 485)
yran = random.randint(0, 485)
xran1 = random.randint(5, 450)
yran1 = random.randint(5, 400)
char = pygame.draw.rect(screen, black, (x,y,15,15), 0)
food = pygame.draw.rect(screen, green, (xran,yran,10,10), 0)
badGuy = pygame.draw.rect(screen, red, (xran1,yran1,50,100), 0)
if char.colliderect(food):
score += 1
print "Your score is:",score
allRand()
Does calling a function that regenerates random numbers work for any of you? I know it regenerates them because I have had it print back the variables, for some reason my rects don't do there though.
Note: This is just snippet of my code it was just meant to give an idea of what I am trying to do.
Thanks!
You need to declare xran, etc. with global inside the allRand() function. Otherwise, it's just creating new variables inside function scope, assigning them random values, then throwing them away when the function returns.
Your allRand() method doesn't have any code. You must indent the lines you want in that function.
It's kinda working because you still call those statements below your def. But it's not because you're calling the function.
To add to Lee Daniel Crocker's answer, when you create variables in a function they exist only in that function. If you want them to exist outside you can either make them global variables as he suggested, you are can return them and catch them:
>>> def square(number):
squared = number*number
return squared
>>> square(3)
9
>>> ninesquared = square(3)
>>> ninesquared
9
>>>
Read more
It looks like you need to master your basics. I suggest doing that first before trying things in pygame.
EDIT:
If you define variables outside of the function, they will not effect any variables you define in the function either.
>>> x = 5
>>> def rais():
x = 10
>>> x
5
>>> rais()
>>> x
5
>>>
Notice how rais did nothing?
If we change the line in rais to be x = x + 1 then python will give us back an error that x is not defined.
If you want you're variables to get into the function you need to pass them in as parameters, but once again, they won't effect anything outside of the function unless you return and capture them. And once again, you can declare them as global variables and that will also work.
Is there a way in matlab to restrict variables in a function
For example i have a function
function S0 = S0Func(obj, c, delta, xT, sigma)
beta = obj.betaFunc(sigma);
xb = obj.xbFunc(c, delta, sigma);
S0 = (1-obj.tau).*(obj.x0./(obj.r-obj.mu)-c./obj.r-(xb./(obj.r-obj.mu)-c./obj.r).*((obj.x0./xb).^beta)-((delta-1).*c./obj.r).*((obj.x0./xT).^beta-((obj.x0./xb).^beta)));
end
where I would like to have the restrictions (obj is an object of a class)
0<xb<xT<1
0<c
1<delta
What I would like to do is to draw a 3d graph of the following with the restrictions mentioned above
S0Func(2.7, 1, 1, 0.3)-S0Func(c,delta,xT,0.2)<0;
EDIT
I have tried using the isosurface
optimalStraightCoupon = fminbnd(#(c) -(S0Function(c,1,1)+D0Function(c,1,1)), 0, 4);
[xT, delta, c] = meshgrid(0.8:.01:1, 1:.1:3, 0:.1:4);
values = S0Function(optimalStraightCoupon,1, 1)- S0Function(c,delta, xT);
patch(isosurface(xT, c, delta, values, 1), 'FaceColor', 'red');
view(3);
I get some output, but it is not correct as the restriction on xT is violated.
Any help is appreciated. Thank you.
It's a little unclear what you are trying to achieve. I expect that you know that you can write statements such as (pseudocode):
if c>=0 exit
which, in a sense, restricts your function to operate only on values which meet the defined constraints.
The foregoing is so simple that I am sure that I have misunderstood your question.
No, it appears you wish MORE than a just 3-d graph. It appears you wish to see this function as a FUNCTION of three variables: c, delta, xT. So a 4-d graph. In that event, you will need to simply evaluate the function over a 3-d mesh (using meshgrid or ndgrid to generate the points.)
Then use isosurface to visualize the result, as essentially a higher dimensional contour plot. Do several such plots, at different iso-levels.
I would just return NaN when your constraints are violated.
Just add following lines to your function (preferable before the calculation to save time)
if delta <= 1 || c <= 0 || ... % I assume you can write them yourself
S0 = NaN;
return
end
Plot will not draw NaNs.
Though as you input c,delta,xT it's the question why they are set to invalid values in the first place. You could save some checks and therefore time if you assure that beforehand.