I want to plot a 3D graph with points (I think I have managed that) and also fitting a mathematical function of set of that points. My variable V1 can assume two values 2 or 4. So, If V1 is equal to 2 a function is plotting, else if V1 is equal to 4 other function is plotting. When I try do it this message appear:
Erro de GPL: algebra(iter(5000,1000000,10)DOIF(V1=2).)
Expecting ( or + or * or /: iter(5000,1000000,10)DOIF(V1=2)
My code:
> GGRAPH /GRAPHDATASET NAME="graphdataset" VARIABLES=V2 pacpop V1
> MISSING=LISTWISE REPORTMISSING=NO /GRAPHSPEC SOURCE=INLINE. BEGIN
> GPL SOURCE: s=userSource(id("graphdataset"))
>DATA:V2=col(source(s), name("V2"))
>DATA: pacpop=col(source(s),name("pacpop"))
>DATA: V1=col(source(s), name("V1"),unit.category())
>COORD: rect(dim(1,2,3))
>GUIDE: axis(dim(1),label("Sexo"))
> GUIDE: axis(dim(2), label("Rendimento Mensal"))
> GUIDE: axis(dim(3), label("pacpop"))
>SCALE: log(dim(2), base(10))
>SCALE: log(dim(3), base(10))
>SCALE: cat(dim(1), include("2", "4"))
> ELEMENT: point(position(V1*V2*pacpop))
>DATA: p = iter(0,5000,1)
> DATA: q = iter(5000,1000000,10)
>DATA: x = iter(0,5000,1)
>DATA: z =iter(5000,1000000,10)
>DO IF (V1=2).
>TRANS: y =eval(100*exp((-x/1654.97))
> TRANS: w = eval((10**8.865)/(z**2.186))
> ELEMENT: line(position(V1*x*y),color.interior(color."ff0000"))
> ELEMENT: line(position(V1*z*w), color.interior(color."ff0000"))
> ELSE.
> TRANS: r = eval(100*exp((-p/1415.97))
>TRANS: s = eval((10**7.065)/(q**2.216))
>ELEMENT:line(position(V1*p*r),color.interior(color."ff0000"))
ELEMENT:line(position(V1*q*s), color.interior(color."ff0000"))
>END IF.
> END GPL.
There is no need to use 3d here. Since V1 can only take two values, you can simply superimpose those lines onto the same plot and see where they diverge, example below. Note I changed p to range from 1 to 5000, you can't take the log of 0.
GGRAPH /GRAPHSPEC SOURCE=INLINE.
BEGIN GPL
COORD: rect(dim(1,2))
DATA: p = iter(1,5000,1)
DATA: q = iter(5000,1000000,10)
TRANS: y =eval(100*exp((-p/1654.97))
TRANS: w = eval((10**8.865)/(q**2.186))
TRANS: r = eval(100*exp((-p/1415.97))
TRANS: s = eval((10**7.065)/(q**2.216))
TRANS: V2 = eval("V1=2")
TRANS: V4 = eval("V1=4")
SCALE: log(dim(1), base(10))
SCALE: log(dim(2), base(10))
GUIDE: axis(dim(3), opposite())
ELEMENT: line(position(p*y), color.interior(color.red))
ELEMENT: line(position(q*w), color.interior(color.pink))
ELEMENT: line(position(p*r),color.interior(color.blue))
ELEMENT: line(position(q*s), color.interior(color.lightblue))
END GPL.
You can work out from there to plot 3d if you really want to, but I would not recommend it.
Related
I've been trying to solve an equation for a 2D vector P.
But after solve there are still some P on the rhs.
Does this mean Maxima can't do it or I've done something wrong?
Here is it:
load("vect");
declare(".", commutative);
declare(P, nonscalar);
declare([v1,V1,r1], nonscalar);
declare([v2,V2,r2], nonscalar);
declare([w1,W1,m1,I1,w2,W2,m2,I2], scalar);
/* Revolute Constraint */
constraint: v2 + (w2~r2) - (v1 + (w1~r1)) = 0$
/* Velocities after impulse P */
eq1: v1 = V1 - P/m1$
eq2: w1 = W1 - (r1~P) / I1$
eq3: v2 = V2 + P/m2$
eq4: w2 = W2 + (r2~P) / I2$
eq: subst([eq1,eq2,eq3,eq4], constraint)$
solve(eq, P);
(I'm trying to get an equation for an impulse that satisfies the constraint.
I'm following Dirk Gregorius' 2nd post here: https://gamedev.net/forums/topic/469531-revolute-joint-usingimpulses/4086845)
I think I've worked out the details. I had to do some stuff by hand, and Maxima was mostly just checking that I did it correctly. If the goal is just to get to a solution, I guess that's okay.
Here's my script. You can execute this via: maxima --batch=foo.mac where foo.mac is the name of the script.
/* adapted from: https://stackoverflow.com/questions/69700162/equation-not-fully-solved
*/
load("vect");
/* I don't want to reorder arguments of cross product. */
remrule ("~", ?\~rule4);
/* I do want to flatten noncommutative multiplication.
* (It appears that's disabled by vect; ordinarily it happens by default.)
*/
dotassoc: true $
declare(P, nonscalar);
declare([v1,w1,V1,W1,r1], nonscalar);
declare([v2,w2,V2,W2,r2], nonscalar);
declare([m1,I1,m2,I2], scalar);
/* Revolute Constraint */
constraint: v2 - (r2~w2) - (v1 - (r1~w1)) = 0$
/* Velocities after impulse P */
eq1: v1 = V1 - P/m1$
eq2: w1 = W1 - (r1~P) / I1$
eq3: v2 = V2 + P/m2$
eq4: w2 = W2 + (r2~P) / I2$
eq: subst([eq1,eq2,eq3,eq4], constraint);
A(a) := matrix([0, -a[3], a[2]], [a[3], 0, -a[1]], [-a[2], a[1], 0]);
eqa: ev (eq, (u~v) := 'A(u).v);
matchdeclare (pp, lambda ([e], not freeof(P, e)));
matchdeclare (qq, lambda ([e], freeof(P, e)));
defrule (rp, pp + qq = 0, pp = -qq);
eqa1: expand (eqa);
eqa2: apply1 (eqa1, rp);
matchdeclare (aa, lambda ([e], matrixp(e) or listp(e)));
tellsimpafter (I(aa), ident (length (aa)));
matchdeclare ([aa, bb], all);
tellsimpafter (I(aa) . bb, bb);
tellsimpafter (aa . I(bb), aa);
M: -(1/I2)*'A(r2).'A(r2) - (1/I1)*'A(r1).'A(r1) + (1/m2)*I(P) + (1/m1)*I(P);
N: 'A(r2).W2 - 'A(r1).W1 - V2 + V1;
eqa2_factored: M . P = N;
expand (eqa2_factored);
?resimplify (%);
if % # eqa2 then error ("tried to factor eqa2, but something went wrong.");
solution: P = M^^-1 . N;
/* EXAMPLE: */
I1: 20 $
I2: 3 $
m1: 100 $
m2: 12 $
V1: [17, 19, -23] $
V2: [-5, -3, 11] $
W1: [8, 4, 14] $
W2: [-6, -16, 24 ] $
r1: [1/2, 2/3, 3/4] $
r2: [5, 7, 3] $
/* note various subterfuges to ensure evaluation with stated values */
example_M: ev (subst (I(P) = ident(3), M), nouns);
example_N: ev (N, nouns);
example_P: example_M^^-1 . example_N;
subst (P = example_P, ev (eqa2, eval, nouns));
if lhs(%) = rhs(%)
then print ("TEST PASSED: lhs = rhs")
else error ("TEST FAILED: lhs # rhs");
If you need to evaluate P for different parameters r1, r2, etc., my advice is to evaluate matrix M and vector N with whatever values you want to plug in, and then solve the equation P = M^^-1 . N. An explicit solution is probably going to be pretty messy.
Following Robert Dodier's advice, I broke up all the vectors and solved for P[1] and P[2] individually.
I've got something that gives me an answer but now how can I get it into nice vector form?
Here it is:
load("vect");
declare(".", commutative);
declare(P, nonscalar);
declare([v1,V1,r1], nonscalar);
declare([v2,V2,r2], nonscalar);
declare([w1,W1,m1,I1], scalar);
declare([w2,W2,m2,I2], scalar);
cross_scalar_vector(s,v) := [-s*v[2], s*v[1]]$
/* Revolute Constraint on Linear Velocity */
constraint: v2 + cross_scalar_vector(w2,r2) - (v1 + cross_scalar_vector(w1,r1)) = [0,0]$
/* Sub in velocities after impulse P. */
post_velocities: [
v1 = V1 - P/m1,
w1 = W1 - (r1~P) / I1,
v2 = V2 + P/m2,
w2 = W2 + (r2~P) / I2
]$
constraint: subst(post_velocities, constraint)$
/* Break up the remaining vectors for solve. */
vectors: [
P = [P[1], P[2]],
V1 = [V1[1], V1[2]],
r1 = [r1[1], r1[2]],
V2 = [V2[1], V2[2]],
r2 = [r2[1], r2[2]]
]$
constraint: subst(vectors, constraint)$
/* Break up vector constraint into x and y constraint for solve. */
xconstraint: lhs(constraint)[1] = 0$
yconstraint: lhs(constraint)[2] = 0$
/* Not sure why we need to do this again? */
xconstraint: subst(vectors, xconstraint)$
yconstraint: subst(vectors, yconstraint)$
/* Expand cross products for solve. */
xconstraint: express(xconstraint)$
yconstraint: express(yconstraint)$
solve([xconstraint,yconstraint], [P[1],P[2]]);
How can one specify link functions in glmnet for lasso / ridge / elastic net regression?
I have found the following post but not sure this helps me when I need to specify a cloglog link.
How to specify log link in glmnet?
I have a survey data set with binary response 0/1 (disease no/yes) and several predictor variables, which are mostly binary categorical (yes/no, male/female), some are counts (herd size), and a few are categorical with several levels.
I previously ran a generalized linear mixed model using glmer() function with binomial family and link = cloglog as doing so created the exact interpretation of the resulting intercept that I wanted (in disease study the intercept from this setup is equivalent to the mean value 'force of infection' - the rate at which susceptibles become infected - among the variation specified in the random effect (in my case the geographic unit (village or subvillage or household).
As there are several survey variables now available to me, I wanted to try a lasso and a ridge regression using glmnet. It is my understanding that I should best do this by putting in the glmm formula into the glmnet. However, I cannot find any documentation about how to add a link. I did so, in the syntax I thought would work, and it did run. But it also ran with nonsense entered in the link function.
Here is a reproducible example:
library(msm)
library(glmnet)
set.seed(1)
N = 1000
X = cbind( rbinom(n=N,size=1,prob=0.5), rnorm(n=N) )
beta = c(-0.1,0.1)
phi.true = exp( X%*%beta )
p = 1 - exp(-phi.true)
y = rbinom(n=N,size=1,prob = p)
dat <- data.frame(x=X,y=y)
x <- model.matrix(y~., dat)
glmnet(x, y, family="binomial", link="logit", alpha = 1, lambda = 2)
I get the same output whether I put in 'logit', 'cloglog' or even a name 'adam'. And cannot use same syntax as GLMM as in glmnet must be a character vector.
OUTPUT:
> glmnet(x, y, family="binomial"(link="logit"), alpha = 1, lambda = 2)
Error in match.arg(family) : 'arg' must be NULL or a character vector
> glmnet(x, y, family="binomial", link="logit", alpha = 1, lambda = 2)
Call: glmnet(x = x, y = y, family = "binomial", alpha = 1, lambda = 2, link = "logit")
Df %Dev Lambda
1 0 -7.12e-15 2
> glmnet(x, y, family="binomial", link="cloglog", alpha = 1, lambda = 2)
Call: glmnet(x = x, y = y, family = "binomial", alpha = 1, lambda = 2, link = "cloglog")
Df %Dev Lambda
1 0 -7.12e-15 2
> glmnet(x, y, family="binomial", link="adam", alpha = 1, lambda = 2)
Call: glmnet(x = x, y = y, family = "binomial", alpha = 1, lambda = 2, link = "adam")
Df %Dev Lambda
1 0 -7.12e-15 2
Is it not possible to change the default link function for binomial family in glmnet?
I think you want to use family = binomial(link = "cloglog")
See the new glmnet vignette: https://cran.r-project.org/web/packages/glmnet/vignettes/glmnetFamily.pdf
I was reading about preallocation from Performance Tips and it has this example:
function xinc!(ret::AbstractVector{T}, x::T) where T
ret[1] = x
ret[2] = x+1
ret[3] = x+2
nothing
end
function loopinc_prealloc()
ret = Array{Int}(3)
y = 0
for i = 1:10^7
xinc!(ret, i)
y += ret[2]
end
y
end
I see that the example is trying to change ret which is preallocated. However, when I tried the following:
function addSparse!(sp1, sp2)
sp1 = 2*sp2
nothing
end
function loopinc_prealloc()
sp1 = spzeros(3, 3)
y = 0
for i = 1:10^7
sp2 = sparse([1, 2], [1, 2], [2 * i, 2 * i], 3, 3)
addSparse!(sp1, sp2)
y += sp1[1,1]
end
y
end
I don't think sp1 is updated by addSparse!. In the example from Julia, function xinc! modifies ret one by one. How can I do the same to a sparse matrix?
In my actual code, I need to update a big sparse matrix in a loop for the sake of saving memory it makes sense for me to preallocate.
The issue is not that the Matrix is sparse. The issue is that when you use the assignment operator = you assign the name sp1 to a new object (with value 2sp2), rather than updating the sp1 matrix. Consider the example from performance tips: ret[1] = x does not reassign ret it just modifies it's elements.
Use the .= operator instead to overwrite all the elements of a container.
I've been working on a project that renders a Mandelbrot fractal. For those of you who know, it is generated by iterating through the following function where c is the point on a complex plane:
function f(c, z) return z^2 + c end
Iterating through that function produces the following fractal (ignore the color):
When you change the function to this, (z raised to the third power)
function f(c, z) return z^3 + c end
the fractal should render like so (again, the color doesn't matter):
(source: uoguelph.ca)
However, when I raised z to the power of 3, I got an image extremely similar as to when you raise z to the power of 2. How can I make the fractal render correctly? This is the code where the iterations are done: (the variables real and imaginary simply scale the screen from -2 to 2)
--loop through each pixel, col = column, row = row
local real = (col - zoomCol) * 4 / width
local imaginary = (row - zoomRow) * 4 / width
local z, c, iter = 0, 0, 0
while math.sqrt(z^2 + c^2) <= 2 and iter < maxIter do
local zNew = z^2 - c^2 + real
c = 2*z*c + imaginary
z = zNew
iter = iter + 1
end
So I recently decided to remake a Mandelbrot fractal generator, and it was MUCH more successful than my attempt last time, as my programming skills have increased with practice.
I decided to generalize the mandelbrot function using recursion for anyone who wants it. So, for example, you can do f(z, c) z^2 + c or f(z, c) z^3 + c
Here it is for anyone that may need it:
function raise(r, i, cr, ci, pow)
if pow == 1 then
return r + cr, i + ci
end
return raise(r*r-i*i, 2*r*i, cr, ci, pow - 1)
end
and it's used like this:
r, i = raise(r, i, CONSTANT_REAL_PART, CONSTANT_IMAG_PART, POWER)
I'm experimenting with the ImageTransformation function to try to make anamorphic versions of images, but with limited progress so far. I'm aiming for the results you get using the image reflected in a cylindrical mirror, where the image curves around the central mirror for about 270 degrees. The wikipedia article has a couple of neat examples (and I borrowed Holbein's skull from them too).
i = Import["../Desktop/Holbein_Skull.jpg"];
i = ImageResize[i, 120]
f[x_, y_] := {(2 (y - 0.3) Cos [1.5 x]), (2 (y - 0.3) Sin [1.5 x])};
ImageTransformation[i, f[#[[1]], #[[2]]] &, Padding -> White]
But I can't persuade Mathematica to show me the entire image, or to bend it correctly. The anamorphic image should wrap right round the mirror placed "inside" the centre of the image, but it won't. I found suitable values for constants by putting it inside a manipulate (and turning the resolution down :). I'm using the formula:
x1 = a(y + b) cos(kx)
y1 = a(y + b) sin(kx)
Any help producing a better result would be greatly appreciated!
In ImageTransformation[f,img], the function f is such that a point {x,y} in the resulting image corresponds to f[{x,y}] in img. Since the resulting image is basically the polar transformation of img, f should be the inverse polar transformation, so you could do something like
anamorphic[img_, angle_: 270 Degree] :=
Module[{dim = ImageDimensions[img], rInner = 1, rOuter},
rOuter = rInner (1 + angle dim[[2]]/dim[[1]]);
ImageTransformation[img,
Function[{pt}, {ArcTan[-#2, #1] & ## pt, Norm[pt]}],
DataRange -> {{-angle/2, angle/2}, {rInner, rOuter}},
PlotRange -> {{-rOuter, rOuter}, {-rOuter, rOuter}},
Padding -> White
]
]
The resulting image looks something like
anamorphic[ExampleData[{"TestImage", "Lena"}]]
Note that you can a similar result with ParametricPlot and TextureCoordinateFunction, e.g.
anamorphic2[img_Image, angle_: 270 Degree] :=
Module[{rInner = 1,rOuter},
rOuter = rInner (1 + angle #2/#1 & ## ImageDimensions[img]);
ParametricPlot[{r Sin[t], -r Cos[t]}, {t, -angle/2, angle/2},
{r, rInner, rOuter},
TextureCoordinateFunction -> ({#3, #4} &),
PlotStyle -> {Opacity[1], Texture[img]},
Mesh -> None, Axes -> False,
BoundaryStyle -> None,
Frame -> False
]
]
anamorphic2[ExampleData[{"TestImage", "Lena"}]]
Edit
In answer to Mr.Wizard's question, if you don't have access to ImageTransformation or Texture you could transform the image data by hand by doing something like
anamorph3[img_, angle_: 270 Degree, imgWidth_: 512] :=
Module[{data, f, matrix, dim, rOuter, rInner = 1.},
dim = ImageDimensions[img];
rOuter = rInner (1 + angle #2/#1 & ## dim);
data = Table[
ListInterpolation[#[[All, All, i]],
{{rOuter, rInner}, {-angle/2, angle/2}}], {i, 3}] &#ImageData[img];
f[i_, j_] := If[Abs[j] <= angle/2 && rInner <= i <= rOuter,
Through[data[i, j]], {1., 1., 1.}];
Image#Table[f[Sqrt[i^2 + j^2], ArcTan[i, -j]],
{i, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)},
{j, -rOuter, rOuter, 2 rOuter/(imgWidth - 1)}]]
Note that this assumes that img has three channels. If the image has fewer or more channels, you need to adapt the code.