IDL two step graph - graph

I'm struggling with setting a y(x) condition that varies with x range. As an example below, the code wants to plot y=x between x=0 and x=5.1; otherwise y=2x.
Upon compilation, the code spits out the following: Expression must be a scalar or 1 element array in this context:
In other words don't know how to assign an array variable 'x' into if statement.
Thank you all for your help in advance.
PRO test
x = findgen(101.0,start=0)/10.0 ; 0.0 start, 10.0 end increment of 0.1
print,x
if x lt 5.1 then begin
y = 1.0 * x ;
endif else begin
y = 2.0* x
endelse
graph1=plot(x,y,thick=2,NAME=first,/CURRENT, $
linestyle = 0, ytitle=' y',xtitle='x' ) ; O
END

The problem is the test in your IF statement. Use WHERE instead to do something like the following.
y = x ;; need to initialize variable
low = WHERE(x lt 5.1,lw,COMPLEMENT=upp,NCOMPLEMENT=up)
IF (lw[0] GT 0) THEN y[low] = x[low] ;; technically don't need this line
IF (up[0] GT 0) THEN y[upp] = 2e0*x[upp]

Related

what does "argmax().I" mean in Julia

Here is the great example from StatWithJuliaBook (please find the following)
It demos how to smooth a plot of stary sky stars.png
My question is about argmax().I. According to the author, "Note the use of the trailing “.I” at the end of each argmax, which extracts the values of the co-ordinates in column-major."
What does it mean? Is there other parameter? I can't find any description in the document.
According to author, it seems to be the position of column-wise maxmum value, yet when I tried argmax(gImg, dims=2), the result is different.
#julia> yOriginal, xOriginal = argmax(gImg).I
#(192, 168)
#julia> yy, xx = argmax(gImg, dims = 2)
#400×1 Matrix{CartesianIndex{2}}:
# CartesianIndex(1, 187)
# CartesianIndex(2, 229)
⋮
# CartesianIndex(399, 207)
# CartesianIndex(400, 285)
#julia> yy, xx
#(CartesianIndex(1, 187), CartesianIndex(2, 229))
Please advise.
using Plots, Images; pyplot()
img = load("stars.png")
gImg = red.(img)*0.299 + green.(img)*0.587 + blue.(img)*0.114
rows, cols = size(img)
println("Highest intensity pixel: ", findmax(gImg))
function boxBlur(image,x,y,d)
if x<=d || y<=d || x>=cols-d || y>=rows-d
return image[x,y]
else
total = 0.0
for xi = x-d:x+d
for yi = y-d:y+d
total += image[xi,yi]
end
end
return total/((2d+1)^2)
end
end
blurImg = [boxBlur(gImg,x,y,5) for x in 1:cols, y in 1:rows]
yOriginal, xOriginal = argmax(gImg).I
yBoxBlur, xBoxBlur = argmax(blurImg).I
p1 = heatmap(gImg, c=:Greys, yflip=true)
p1 = scatter!((xOriginal, yOriginal), ms=60, ma=0, msw=4, msc=:red)
p2 = heatmap(blurImg, c=:Greys, yflip=true)
p2 = scatter!((xBoxBlur, yBoxBlur), ms=60, ma=0, msw=4, msc=:red)
plot(p1, p2, size=(800, 400), ratio=:equal, xlims=(0,cols), ylims=(0,rows),
colorbar_entry=false, border=:none, legend=:none)
I is a field in an object of type CartesianIndex which is returned by argmax when its argument has more than 1 dimension.
If in doubt always try using dump.
Please consider the code below:
julia> arr = rand(4,4)
4×4 Matrix{Float64}:
0.971271 0.0350186 0.20805 0.284678
0.348161 0.19649 0.30343 0.291894
0.385583 0.990593 0.216894 0.814146
0.283823 0.750008 0.266643 0.473104
julia> el = argmax(arr)
CartesianIndex(3, 2)
julia> dump(el)
CartesianIndex{2}
I: Tuple{Int64, Int64}
1: Int64 3
2: Int64 2
However, getting CartesianIndex object data via its internal structure is not very elegant. The nice Julian way to do it is to use the appropriate method:
julia> Tuple(el)
(3, 2)
Or just access the indices directly:
julia> el[1], el[2]
(3, 2)

Unable to plot solution of ODE in Maxima

Good time of the day!
Here is the code:
eq:'diff(x,t)=(exp(cos(t))-1)*x;
ode2(eq,x,t);
sol:ic1(%,t=1,x=-1);
/*---------------------*/
plot2d(
rhs(sol),
[t,-4*%pi, 4*%pi],
[y,-5,5],
[xtics,-4*%pi, 1*%pi, 4*%pi],
[ytics, false],
/*[yx_ratio , 0.6], */
[legend,"Solution."],
[xlabel, "t"], [ylabel, "x(t)"],
[style, [lines,1]],
[color, blue]
);
and here is the errors:
integrate: variable must not be a number; found: -12.56637061435917
What went wrong?
Thanks.
Here's a way to plot the solution sol which was found by ode2 and ic2 as you showed. First replace the integrate nouns with calls to quad_qags, a numerical quadrature function. I'll introduce a made-up variable name (a so-called gensym) to avoid confusion with the variable t.
(%i59) subst (nounify (integrate) =
lambda ([e, xx],
block ([u: gensym(string(xx))],
quad_qags (subst (xx = u, e), u, -4*%pi, xx)[1])),
rhs(sol));
(%o59) -%e^((-t)-quad_qags(%e^cos(t88373),t88373,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]
+quad_qags(%e^cos(t88336),t88336,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]+1)
Now I'll define a function foo1 with that result. I'll make a list of numerical values to see if it works right.
(%i60) foo1(t) := ''%;
(%o60) foo1(t):=-%e
^((-t)-quad_qags(%e^cos(t88373),t88373,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]
+quad_qags(%e^cos(t88336),t88336,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]+1)
(%i61) foo1(0.5);
(%o61) -1.648721270700128
(%i62) makelist (foo1(t), t, makelist (k, k, -10, 10));
(%o62) [-59874.14171519782,-22026.46579480672,
-8103.083927575384,-2980.957987041728,
-1096.633158428459,-403.4287934927351,
-148.4131591025766,-54.59815003314424,
-20.08553692318767,-7.38905609893065,-2.71828182845904,
-1.0,-0.3678794411714423,-0.1353352832366127,
-0.04978706836786394,-0.01831563888873418,
-0.006737946999085467,-0.002478752176666358,
-9.118819655545163E-4,-3.354626279025119E-4,
-1.234098040866796E-4]
Does %o62 look right to you? I'll assume it is okay. Next I'll define a function foo which calls foo1 defined before when the argument is a number, otherwise it just returns 0. This is a workaround for a bug in plot2d, which incorrectly determines that foo1 is not a function of t alone. Usually that workaround isn't needed, but it is needed in this case.
(%i63) foo(t) := if numberp(t) then foo1(t) else 0;
(%o63) foo(t):=if numberp(t) then foo1(t) else 0
Okay, now the function foo can be plotted!
(%i64) plot2d (foo, [t, -4*%pi, 4*%pi], [y, -5, 5]);
plot2d: some values were clipped.
(%o64) false
That takes about 30 seconds to plot -- calling quad_qags is relatively expensive.
it looks like ode2 does not know how to completely solve the problem, so the result contains an integral:
(%i6) display2d: false $
(%i7) eq:'diff(x,t)=(exp(cos(t))-1)*x;
(%o7) 'diff(x,t,1) = (%e^cos(t)-1)*x
(%i8) ode2(eq,x,t);
(%o8) x = %c*%e^('integrate(%e^cos(t),t)-t)
(%i9) sol:ic1(%,t=1,x=-1);
(%o9) x = -%e^((-%at('integrate(%e^cos(t),t),t = 1))
+'integrate(%e^cos(t),t)-t+1)
I tried it with contrib_ode also:
(%i12) load (contrib_ode);
(%o12) "/Users/dodier/tmp/maxima-code/share/contrib/diffequations/contrib_ode.mac"
(%i13) contrib_ode (eq, x, t);
(%o13) [x = %c*%e^('integrate(%e^cos(t),t)-t)]
So contrib_ode did not solve it completely either.
However the solution returned by ode2 (same for contrib_ode) appears to be a valid solution. I'll post a separate answer describing how to evaluate it numerically for plotting.

Julia NLopt force stops before the first iteration

I'm using NLopt for a constrained maximization problem. Regardless of the algorithm or start values, the optimization program is force stopped even before the first iteration (or so I assume because it gives me the initial value). I've attached my code here. I'm trying to find probabilities attached to a grid such that a function is maximized under some constraints. Any help is appreciated.
uk = x -> x^0.5
function objective(u,p,grd)
-p'*u.(grd)
end
function c3(grd,p)
c =[]
d =[]
for i=1:length(grd)
push!(c,quadgk(x -> (i-x)*(x <= i ? 1 : 0),0,1)[1])
push!(d,sum(p[1:i]'*(grd[1:i] .- grd[i])))
end
return append!(d-c,-p)
end
function c4(grd,p)
return (grd .* p)-quadgk(x,0,1)
end
grd = n -> collect(0:1/n:1)
opt = Opt(:LD_SLSQP,11)
inequality_constraint!(opt, p -> c3(grd(10),p))
inequality_constraint!(opt, p -> -p)
equality_constraint!(opt, p -> sum(p)-1)
equality_constraint!(opt, p -> c4(grd(10),p))
opt.min_objective = p -> objective(-uk, p, grd(10))
k = push!(ones(11)*(1/11))
(minf,minx,ret) = optimize(opt, k)
I'm not a julia developer, but I only know this, if you need exit before complete the loop for is not your best choice, you need do a while with a sentinel variable.
here you have an article that explain you how while with sentinels works
and here you have a julia example changing your for to a while with a sentinel that exit after the third loop
i = 1
third = 0
while i < length(grd) && third != 1
# of course you need change this, it is only an example that will exit in the 3 loop
if i == 3
third = 1
end
push!(c,quadgk(x -> (i-x)*(x <= i ? 1 : 0),0,1)[1])
push!(d,sum(p[1:i]'*(grd[1:i] .- grd[i])))
i += 1
end

Maple: How to give values to assumptions for plotting?

So I have a simple example of what I want to do:
restart;
assume(can, real);
f := {g = x+can*x*y, t = x+x*y};
assign(f[1]); g;
can := 2;
plot3d(g, x = 0 .. 100, y = 0 .. 100);
while this works:
restart;
f := {g = x+can*x*y, t = x+x*y};
assign(f[1]);
can := 2;
plot3d(g, x = 0 .. 100, y = 0 .. 100);
But that assumptions are really important for my real life case (for some optimisations with complex numbers) so I cant just leve can not preassumed.
Why it plots nothuing for me and how to make it plot?
The expression (or procedure) to be plotted must evaluate to a numeric, floating-point quantity. And so, for your expression g, the name can must have a specific numeric value at the time any plot of g is generated.
But you can produce a sequence of 3D plots, for various values of can, and display them. You can display them all at once, overlaid. Or you can display them in an animated sequence. And you can color or shade them each differently, to give a visual cue that can is changing and different for each.
restart;
f := {g = x+can*x*y, t = x+x*y};
eval(g,f);
N:=50:
Pseq := seq(
plot3d(eval(g,f),
x=0..10,y=0..10,
color=RGB(0.5,0.5,can/(2*N)),
transparency=0.5*(can/(N+1))),
can=1 .. N):
plots:-display(Pseq, axes=box);
plots:-display([Pseq],insequence=true,axes=box);
By the way, you don't have to assign to g just for the sake of using the equation for g that appears inside f. Doing that assignment (using assign, say, like you did) makes it more awkward for you subsequently to create other equations in terms of the pure name g unless you first unassign the name g. Some people find it easier to not make the assignment to g at all for such tasks, and to simply use eval as I've done above.
Now on to your deeper problem. You create an expression containing a local, assumed name. and then later on you want to use the same expression but with the global, unassumed version of that name. You can create the expression, with it containing the global, unassumed name instead of the local, assumed name, buy performing a substitution.
restart;
assume(can, real);
f := {g = x+can*x*y, t = x+x*y};
{g = x + can~ x y, t = x + x y}
assign(f[1]);
g;
x + can~ x y
can := 2:
g;
x + can~ x y
# This fails, because g contains the local name can~
plot3d(g, x=0..100, y=0..100);
# A procedure to make the desired substitution
revert:=proc(nm::name)
local len, snm;
snm:=convert(nm,string);
len:=length(snm);
if snm[-1]="~" then
return parse(snm[1..-2]);
else return parse(nm);
end if;
end proc:
# This is the version of the expression, but with global name can
subsindets(g,`local`,revert);
x + can x y
# This should work
plot3d(subsindets(g,`local`,revert),
x=0..100,y=0..100);

How to arrange elements of vector in Fortran?

I have two p*n arrays, y and ymiss. y contains real numbers and NA's. ymiss contains 1's and 0's, so that if y(i,j)==NA, ymiss(i,j)==0, and 1 otherwise. I also have 1*n array ydim which tells how many real numbers there is at y(1:p,n), so ydim has values 0 to p
In R programming language, I can do following:
if(ydim!=p && ydim!=0)
y(1:ydim(t), t) = y(ymiss(,t), t)
That code arranges all real numbers of y(,t) in like this
first there's for example
y(,t) = (3,1,NA,6,2,NA)
after the code it's
y(,t) = (3,1,6,2,2,NA)
Now I will only need those first 1:ydim(t), so it doesn't matter what those rest are.
The question is, how can I do something like that in Fortran?
Thanks,
Jouni
The "where statement" and the "merge" intrinsic function are powerful, operating on selected positions in arrays, but they don't move items to the front of an array. With old-fashioned code with explicit indexing (could be packaged into a function) e.g.:
k=1
do i=1, n
if (ymiss (i) == 1) then
y(k) = y(i)
k = k + 1
end if
end do
What you want could be done with array intrinsics using the "pack" intrinsic. Convert ymiss into a logical array: 0 --> .false., 1 --> .true.. Then use code like (tested without the second index):
y(1:ydim(t), t) = pack (y (:,t), ymiss (:,t))
Edit to add example code, showing use of Fortran intrinsics "where", "count" and "pack". "where" alone can't solve the problem, but "pack" can. I used "< -90" as NaN for this example. The step "y (ydim+1:LEN) = -99.0" isn't required by the OP, who doesn't need to use these elements.
program test1
integer, parameter :: LEN = 6
real, dimension (1:LEN) :: y = [3.0, 1.0, -99.0, 6.0, 2.0, -99.0 ]
real, dimension (1:LEN) :: y2
logical, dimension (1:LEN) :: ymiss
integer :: ydim
y2 = y
write (*, '(/ "The input array:" / 6(F6.1) )' ) y
where (y < -90.0)
ymiss = .false.
elsewhere
ymiss = .true.
end where
ydim = count (ymiss)
where (ymiss) y2 = y
write (*, '(/ "Masking with where does not rearrange:" / 6(F6.1) )' ) y2
y (1:ydim) = pack (y, ymiss)
y (ydim+1:LEN) = -99.0
write (*, '(/ "After using pack, and ""erasing"" the end:" / 6(F6.1) )' ) y
stop
end program test1
Output is:
The input array:
3.0 1.0 -99.0 6.0 2.0 -99.0
Masking with where does not rearrange:
3.0 1.0 -99.0 6.0 2.0 -99.0
After using pack, and "erasing" the end:
3.0 1.0 6.0 2.0 -99.0 -99.0
In Fortran you can't store na in an array of real numbers, you can only store real numbers. So you'll probably want to replace na's with some value not likely to be present in your data: huge() might be suitable. 2D arrays are no problem at all for Fortan. You might want to use a 2D array of logicals to replace ymiss rather than a 2D array of 1s and 0s.
There is no simple, intrinsic to achieve what you want, you'd need to write a function. However, a more Fortran way of doing things would be to use the array of logicals as a mask for the operations you want to carry out.
So, here's some fragmentary Fortran code, not tested:
! Declarations
real(8), dimension(m,n) :: y, ynew
logical, dimension(m,n) :: ymiss
! Executable
where (ymiss) ynew = func(y) ! here func() is whatever your function is

Resources