Why is a function parameter considered an undefined variable? - matlab

I've been looking around for a while, but I can't seem to find something that describes and answers the problem I've been having. Namely, I have a function being defined in a ball class that checks to see if it and another ball are intersecting (due to the balls being kept on the same z-plane and the radius being the same for all of them, I've simplified the problem to that of intersecting circles). This function is as follows (where both obj and other are of the class ball, and where the ball class contains a position vector of length 3):
function intersected = ball_intersection(obj, other)
intersected = (obj.position(1)-other.position(1))^2+(obj.position(2)-other.position(2))^2 <= (2*ball.radius)^2;
end
I get the following error:
Undefined variable other.
Error in ball/ball_intersection (line 29)
intersected = (obj.position(1)-other.position(1))^2+(obj.position(2)-other.position(2))^2 <= (2*ball.radius)^2;
Error in ball/move (line 56)
if ball_intersection(other)
Error in finalproject (line 41)
cueball.move(0.0001, 0, 0, 9.32, 4.65, otherball);
For some reason, Matlab thinks that a function parameter is undefined, and I don't know how to make it know that it is in fact defined right there.
Any and all help is appreciated - thanks for reading!

ball_intersection has to be called with two input arguments.
Most likely, you want to change line 56 of ball to if ball_intersection(obj,other), or if obj.ball_intersection(other).

Related

Trying to draw a partial dependence plot but an error is reported

I tried to build the gbm model and prepared a partial dependence plot of the variables but got an error.
partial(gbm.fit.final,pred.var = "lstat", n.trees = gbm.fit.final$n.trees, grid.resolution = 100)
Error in copy_classes(pred.grid, train) :
sapply(x[column.names], class) and sapply(y[column.names], class) are not equal:
Lengths: 1, 2
names for target but not for current
Attributes: < names for current but not for target >
....
I'm not sure what's wrong, please fix this problem.

I don't understand RaycastCommand

Documentation (https://docs.unity3d.com/2019.2/Documentation/ScriptReference/RaycastCommand.html) says:
If maxHits is larger than the actual number of results for the command
the result buffer will contain some invalid results which did not hit
anything. The first invalid result is identified by the collider being
null. The second and later invalid results are not written to by the
raycast command so their colliders are not guaranteed to be null. When
iterating over the results the loop should stop when the first invalid
result is found.
Soo, having
new RaycastCommand(from, direction, 4);
How can i distinguish if i had no hits vs when result is invalid? Both cases have hit.collider == null.
If collides with multiple elements, rather than returning the nearest colliding one, it will return nothing??
RaycastHit is a struct type thus itself can never be null. So as the docs says
The first invalid result is identified by the collider being null.
NOTE: The order of the (optional) parameters in the constructor if not explicitly named is
new RaycastCommand(Vector3 from, Vector3 direction, float distance, int layerMask, int maxHits);
and their default values are
distance = float.MaxValue
layerMask = -5
maxHits = 1
Again in words: The default value for maxHits is 1!
Unfortunately this is not visible in the docs but your IDE should reveal that.
Knowing this now you can see that your current example
new RaycastCommand(from, direction, 4);
actually says: The maximum distance of the ray is 4 but still allows only 1 single hit!
If you rather wanted to have 4 possible hits you have to call it as
new RaycastCommand(from, direction, maxHits: 4);
now if you call it like this a buffer with exactly 4 RaycastHit entries will be created, no matter how many objects are hit or if any at all.
Then nothing was hit at all if
results[0].collider == null
and since unfortunately
The second and later invalid results are not written to by the raycast command so their colliders are not guaranteed to be null.
you would have to filter them e.g. like
var validResults = new List<RaycastHit>();
foreach(var r in results)
{
if(r.collider == null) break;
validResults.Add(r);
}
Then you could further also sort them to "nearest first" using Linq like e.g.
using System.Linq;
...
var orderedResults = validResults.OrderBy(r=>r.distance).ToList();
// Which is basically a shorthand for something like the following
// not sure though how Linq does it internally, I hope it does something more efficient ^^
var orderedResults = new List<RaycastHit>();
foreach(var r in validResults)
{
for(int i = 0; i < orderedResults.Count; i ++)
{
if(orderedResults[i].distance <= r.distance)
{
orderesResult.Insert(i + 1, r);
break;
}
}
}

How to overcome indefinite matrix error (NbClust)?

I'm getting the following error when calling NbClust():
Error in NbClust(data = ds[, sapply(ds, is.numeric)], diss = NULL, distance = "euclidean", : The TSS matrix is indefinite. There must be too many missing values. The index cannot be calculated.
I've called ds <- ds[complete.cases(ds),] just before running NbClust so there's no missing values.
Any idea what's behind this error?
Thanks
I had same issue in my research.
So, I had mailed to Nadia Ghazzali, who is the package maintainer, and got an answer.
I'll attached my mail and her reply.
my e-mail:
Dear Nadia Ghazzali. Hello Nadia. I have some questions about
NbClust function in R library. I have tried googling but could not
find satisfying answers. First, I’m so grateful for you to making
this awsome R library. It is very helpful for my reasearch. I tested
NbClust function in NbClust library with my own data like below.
> clust <- NbClust(data, distance = “euclidean”,
min.nc = 2, max.nc = 10, method = ‘kmeans’, index =”all”)
But soon, an error has occurred. Error: division by zero! Error in
Indices.WBT(x = jeu, cl = cl1, P = TT, s = ss, vv = vv) : object
'scott' not found So, I tried NbClust function line by line and
found that some indices, like CCC, Scott, marriot, tracecovw,
tracew, friedman, and rubin, were not calculated because of object
vv = 0. I’m not very familiar with argebra so I don’t know meaning
of eigen value. But it seems to me that object ss(which is squart of
eigenValues) should not be 0 after prodected.
So, here is my questions.
I assume that my data is so sparse(a lot of zero values) that sqrt(eigenValues) becomes too small, is that right? I’m sorry I
can’t attach my data but I can attach some part of eigenValues and
squarted eigenValues.
> head(eigenValues)
[1] 0.039769880 0.017179826 0.007011972 0.005698736 0.005164871 0.004567238
> head(sqrt(eigenValues))
[1] 0.19942387 0.13107184 0.08373752 0.07548997 0.07186704 0.06758134
And if my assume is right, what can I do for this problems? Only one
way to drop out 7 indices?
Thank you for reading and I’ll waiting your reply. Best regards!
and her reply:
Dear Hansol,
Thank you for your interest. Yes, your understanding is good.
Unfortunately, the seven indices could not be applied.
Best regards,
Nadia Ghazzali
#seni The cause of this error is data related. If you look at the source code of this function,
NbClust <- function(data, diss="NULL", distance = "euclidean", min.nc=2, max.nc=15, method = "ward", index = "all", alphaBeale = 0.1)
{
x<-0
min_nc <- min.nc
max_nc <- max.nc
jeu1 <- as.matrix(data)
numberObsBefore <- dim(jeu1)[1]
jeu <- na.omit(jeu1) # returns the object with incomplete cases removed
nn <- numberObsAfter <- dim(jeu)[1]
pp <- dim(jeu)[2]
TT <- t(jeu)%*%jeu
sizeEigenTT <- length(eigen(TT)$value)
eigenValues <- eigen(TT/(nn-1))$value
for (i in 1:sizeEigenTT)
{
if (eigenValues[i] < 0) {
print(paste("There are only", numberObsAfter,"nonmissing observations out of a possible", numberObsBefore ,"observations."))
stop("The TSS matrix is indefinite. There must be too many missing values. The index cannot be calculated.")
}
}
And I think the root cause of this error is the negative eigenvalues that seep in when the number of clusters is very high, i.e. the max.nc is high. So to solve the problem, you must look at your data. See if it got more columns then rows. Remove missing values, check for issues like collinearity & multicollinearity, variance, covariance etc.
For the other error, invalid clustering method, look at the source code of the method here. Look at line number 168, 169 in the given link. You are getting this error message because the clustering method is empty. if (is.na(method))
stop("invalid clustering method")

scipy dblquad providing the wrong result in simple double integral

I am trying to calculate a straightforward doble definite integral in Python: function Max(0, (4-12x) + (6-12y)) in the square [0,1] x [0,1].
We can do it with Mathematica and get the exact result:
Integrate[Max[0, 4-12*u1 + 6-12*u2], {u1, 0, 1}, {u2, 0,1}] = 125/108.
With a simple Monte Carlo simulation I can confirm this result. However, using scipy.integrate.dblquad I am getting a value of 0.0005772072907971, with error 0.0000000000031299
from scipy.integrate import dblquad
def integ(u1, u2):
return max(0, (4 - 12*u1) + (6 - 12*u2))
sol_int, err = dblquad(integ, 0, 1, lambda _:0, lambda _:1, epsabs=1E-12, epsrel=1E-12)
print("dblquad: %0.16f. Error: %0.16f" % (sol_int, err) )
Agreed that the function is not derivable, but it is continuous, I see no reason for this particular integral to be problematic.
I thought maybe dblquad has an 'options' argument where I can try different numerical methods, but I found nothing like that.
So, what am I doing wrong?
try different numerical methods
That's what I would suggest, given the trouble that iterated quad has on Windows. After changing it to an explicit two-step process, you can replace one of quad with another method, romberg seems the best alternative to me.
from scipy.integrate import quad, romberg
def integ(u1, u2):
return max(0, (4 - 12*u1) + (6 - 12*u2))
sol_int = romberg(lambda u1: quad(lambda u2: integ(u1, u2), 0, 1)[0], 0, 1)
print("romberg-quad: %0.16f " % sol_int)
This prints 1.1574073959987758 on my computer, and hopefully you will get the same.

Performing Kernel Density Estimations in MATLAB

I have been using MATLAB to perform Kernel Density Estimations (KDE) on UTM data (X and Y coordinates). I ran into a problem that I do not seem to be understanding.
I perform the KDEs with a sample of 45 points. Everything works fine and I produce the graphs with contours.
[bandwidth,density,X,Y]=kde2d(data)
The function kde2d is code by Zdravko Botev. I obtained it from his file exchange on MathWorks. The variable 'data' is a 45x2 array of my data. The first column holds the X coordinates and the second the Y.
The problem comes when I try to do the same line of code on a subset of those 45 points. I get a recurring error:
Error using fzero (line 274)
The function values at the interval endpoints must differ in sign.
Error in kde2d (line 101)
t_star=fzero(#(t)(t-evolve(t)),[0,0.1]);
I get the same error for a bunch of those subsets on a bunch of different sets of 45 points.
The complete set has these 45 values:
1594436.281 572258.1272
1594418.48 572357.5859
1594471.362 572385.5186
1594516.726 572266.8206
1594415.313 572369.2754
1594519.701 572272.7153
1594415.377 572363.4139
1594468.365 572381.5779
1594518.139 572276.6059
1594425.496 572271.6874
1594524.259 572272.7651
1594502.555 572172.8749
1594516.747 572264.867
1594485.314 572360.2689
1594476.027 572375.7997
1594556.087 572419.6609
1594522.718 572274.7021
1594472.775 572395.3039
1594554.568 572419.6443
1594527.255 572276.7054
1594474.315 572393.3669
1594522.697 572276.6557
1594471.319 572389.4262
1594460.854 572373.6799
1594546.022 572228.0609
1594460.79 572379.5414
1594468.323 572385.4855
1594466.953 572371.7926
1594519.722 572270.7614
1594396.76 572398.3826
1594468.131 572403.0693
1594418.288 572375.1697
1594396.377 572433.5499
1594448.287 572271.9361
1594510.541 572276.523
1594424.466 572226.7345
1594413.773 572371.2124
1594511.848 572296.0774
1594513.367 572296.094
1594424.488 572224.7805
1594468.152 572401.1153
1594421.37 572371.2953
1594446.768 572271.9195
1594468.152 572401.1153
1594448.799 572225.0457
One of the subsets I am trying to use is this:
1594436.281 572258.1272
1594418.48 572357.5859
1594471.362 572385.5186
1594516.726 572266.8206
1594415.313 572369.2754
1594519.701 572272.7153
1594415.377 572363.4139
1594468.365 572381.5779
1594518.139 572276.6059
1594425.496 572271.6874
I am not sure if I should include any of Botev's code. I am hoping that the error message can be explained on its own. If not I can provide more. Thank you very much.