Fitting linear model in Scalanlp/Breeze - scala-breeze

I try to fit a linear model (and get the R^2) to the following test-data
0.0 0.0
1.0 1.0
2.0 2.0
3.0 3.1
I wrote the following code using scalanlp/breeze 0.12 :
import breeze.linalg.{DenseMatrix, DenseVector}
import breeze.stats.regression.leastSquares
val indep = DenseMatrix((1.0, 0.0), (1.0, 1.0), (1.0, 2.0), (1.0, 3.0))
val dep = DenseVector(0.0, 1.0, 2.0, 3.1)
val result = leastSquares(indep, dep)
println("intercept=" + result.coefficients.data(0))
println("slope=" + result.coefficients.data(1))
println("r^2=" + result.rSquared)
the output is:
intercept=-0.020000000000000018
slope=1.03
r^2=0.0014623322596666252
Intercept and slope are reasonable, but I don't understand R-squared, it should be close to 1!

Your vector of ones needs to come last not first. Hence the r^2 = 1-r_e^2 you expected.
EDIT: While what I said above is correct about switching around your vector of 1s. I'm still getting a horribly incorrect r-squared as well even using that. My slope and intercept are spot on though, much like yours. So... to the source code!
EDIT2: Known issue. Hasn't been fixed. shrug

Related

Skyfield topocentric to ICRS transformation. Is there anything like SOFA / ERFA atic13?

I'm currently working on astronomy mount support tool. This need to transform coordinates between JNow and J2000. I've don this using the ERFA implementation in the SOFA library, which is also present in astropy. As I starting in looking after Skyfield for satellite tracking, I want to reduce the number of libraries used.
Actually the transformation from J2000 (or ICRS) to JNow (Topocentric) could be done on ERFA with "atic13" routine:
rc, dc, eo = self.ERFA.atic13(self.ERFA.anp(ra * self.ERFA.D2PI /24 + self.ERFA.eo06a(jdtt, 0.0)),
dec * self.ERFA.D2PI / 360,
<topo julian date>,
0.0)
val1 = rc * 24.0 / self.ERFA.D2PI
val2 = dc * self.ERFA.DR2D
The same way of doing that on Skyfield is
result = earth.at(<topo julian date>).observe(<coordinates>).apparent()
and I could access the coordinates from the result. Now what made me sad, because I might have on the wrong path, I would do it the other way round. So in ERFA it is simply:
ri, di, eo = self.ERFA.atci13(ra * self.ERFA.D2PI / 24,
dec * self.ERFA.D2PI / 360,
0,
0,
0,
0,
<topo julian date>,
0)
val1 = self.ERFA.anp(ri - eo) * 24 / self.ERFA.D2PI
val2 = di * 360 / self.ERFA.D2PI
but I don't find the right way with Skyfield. If somebody could direct me in the right way, this would be very helpful. I'm actually using the newest one (1.6)
Michel
Skyfield does not, alas, currently implement iterative approximations to the inverses of aberration and light deflection — it can only apply them in the usual, forward direction. By contrast, the ERFA routine you reference does indeed reverse them:
“Iterative techniques are used for the aberration and light deflection corrections so that the functions eraAtic13 (or eraAticq) and eraAtci13 (or eraAtciq) are accurate inverses; even at the edge of the Sun's disk the discrepancy is only about 1 nanoarcsecond.”
— https://juliaastro.github.io/ERFA.jl/v0.4/api.html#ERFA.atic13-NTuple{4,Any}
You will want to keep using AstroPy for that transform.

Finding an optimal selection in a 2D matrix with given constrains

Problem statement
Given a m x n matrix where m <= n you have to select entries so that their sum is maximal.
However you can only select one entry per row and at most one per column.
The performance is also a huge factor which means its ok to find selections that are not optimal in oder to reduce complexity (as long as its better than selecting random entries)
Example
Valid selections:
Invalid selections:
(one entry per row and at most one per column)
My Approaches
Select best of k random permutations
A = createRandomMatrix(m,n)
selections = list()
for try in range(k):
cols = createRandomIndexPermutation(m) # with no dublicates
for row in range(m):
sum += A[row, cols[row]]
selections.append(sum)
result = max(selections)
This appoach performs poorly when n is significantly larger than m
Best possible (not yet taken) column per row
A = createRandomMatrix(m,n)
takenCols = set()
result = 0
for row in range(m):
col = getMaxColPossible(row, takenCols, A)
result += A[row, col]
takenCols.add(col)
This approach always values the rows (or columns) higher that were discovered first which could lead to worse than average results
This sounds exactly like the rectangular linear assignment problem (RLAP). This problem can be efficiently (in terms of asymptotic complexity; somewhat around cubic time) solved (to a global-optimum) and a lot of software is available.
The basic approaches are LAP + dummy-vars, LAP-modifications or more general algorithms like network-flows (min-cost max-flow).
You can start with (pdf):
Bijsterbosch, J., and A. Volgenant. "Solving the Rectangular assignment problem and applications." Annals of Operations Research 181.1 (2010): 443-462.
Small python-example using python's common scientific-stack:
Edit: as mentioned in the comments, negating the cost-matrix (which i did, motivated by the LP-description) is not what's done in the Munkres/Hungarian-method literature. The strategy is to build a profit-matrix from the cost-matrix, which is now reflected in the example. This approach will lead to a non-negative cost-matrix (sometimes assumes; if it's important, depends on the implementation). More information is available in this question.
Code
import numpy as np
import scipy.optimize as sopt # RLAP solver
import matplotlib.pyplot as plt # visualizatiion
import seaborn as sns # """
np.random.seed(1)
# Example data from
# https://matplotlib.org/gallery/images_contours_and_fields/image_annotated_heatmap.html
# removed a row; will be shuffled to make it more interesting!
harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0],
[2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0],
[1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0],
[0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0],
[0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0],
[1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1]],)
harvest = harvest[:, np.random.permutation(harvest.shape[1])]
# scipy: linear_sum_assignment -> able to take rectangular-problem!
# assumption: minimize -> cost-matrix to profit-matrix:
# remove original cost from maximum-costs
# Kuhn, Harold W.:
# "Variants of the Hungarian method for assignment problems."
max_cost = np.amax(harvest)
harvest_profit = max_cost - harvest
row_ind, col_ind = sopt.linear_sum_assignment(harvest_profit)
sol_map = np.zeros(harvest.shape, dtype=bool)
sol_map[row_ind, col_ind] = True
# Visualize
f, ax = plt.subplots(2, figsize=(9, 6))
sns.heatmap(harvest, annot=True, linewidths=.5, ax=ax[0], cbar=False,
linecolor='black', cmap="YlGnBu")
sns.heatmap(harvest, annot=True, mask=~sol_map, linewidths=.5, ax=ax[1],
linecolor='black', cbar=False, cmap="YlGnBu")
plt.tight_layout()
plt.show()
Output

Adding measurement errors to pymc model

I have the following model in pymc2:
import pymc
from scipy.stats import gamma
alpha = pymc.Uniform('alpha', 0.01, 2.0)
scale = pymc.Uniform('scale', 1.0, 4.0)
#pymc.deterministic(plot=False)
def beta(scale=scale):
return 1.0 / scale
#pymc.potential
def p_factor(alpha=alpha, scale=scale, lmin=lmin, n=len(sample)):
dist = gamma(alpha, loc=0., scale=scale)
fp = 1.0 - dist.cdf(lmin)
return -(n+1)*np.log(fp)
obs = pymc.Gamma("obs", alpha=alpha, beta=beta, value=sample, observed=True)
The physical background of this model is the luminosity function of galaxies (LF), i.e., the probability of a galaxy having luminosity L. For some types of galaxies, the LF is just a gamma function. The potential accounts for data truncation, as galaxy surveys usually miss a substantial fraction of the targets, particularly those of low luminosity. In this model I miss everything below lmin
Details of this method can be found in this paper by Kelly et al.
This model works: I run MAP and MCMC on the model and I can recover the parameters alpha and scale from my simulated data sample, with increased uncertainty as lmin grows.
Now I would like to insert gaussian measurement errors. For simplicity all the data has the same precision. I'm not modifying the potential to include the errors also.
alpha = pymc.Uniform('alpha', 0.01, 2.0)
scale = pymc.Uniform('scale',1.0, 4.0)
sig = 0.1
tau = math.pow(sig, -2.0)
#pymc.deterministic(plot=False)
def beta(scale=scale):
return 1.0 / scale
#pymc.potential
def p_factor(alpha=alpha, scale=scale, lmin=lmin, n=len(sample)):
dist = gamma(alpha, loc=0., scale=scale)
fp = 1.0 - dist.cdf(lmin)
return -(n+1) * np.log(fp)
dist = pymc.Gamma("dist", alpha=alpha, beta=beta)
obs = pymc.Normal("obs", mu=dist, tau=tau, value=sample, observed=True)
But surely I'm doing something wrong here because this model does not work.
When I run pymc.MAPon this model I recover the initial values of alpha and scale
vals = {'alpha': alpha, 'scale': scale, 'beta': beta,
'p_factor': p_factor, 'obs': obs, 'dist': dist}
M2 = pymc.MAP(vals)
M2.fit()
print M2.alpha.value, M2.scale.value
>>> (array(0.010000000006018368), array(1.000000000833973))
When I run pymc.MCMC, alpha and beta are no traced at all.
M = pymc.MCMC(vals)
M.sample(10000, burn=5000)
...
M.stats()['alpha']
>>> {'95% HPD interval': array([ 0.01000001, 0.01000502]),
'mc error': 2.1442678276712383e-07,
'mean': 0.010001588137798096,
'n': 5000,
'quantiles': {2.5: 0.0100000088679046,
25: 0.010000382359859467,
50: 0.010001100377476166,
75: 0.010001668672799679,
97.5: 0.0100050194240779},
'standard deviation': 2.189828287191421e-06}
again initial values. In fact if I change alpha to start in, say, 0.02, the recovered values of alpha is 0.02.
This is a notebook with the working model plus simulated data.
This is a notebook with the error model plus simulated data.
Any guidance on making this work would be really appreciated.
It seems that is enough to change
dist = pymc.Gamma("dist", alpha=alpha, beta=beta)
by
dist = pymc.Gamma("dist", alpha=alpha, beta=beta, value=sample)
The sampled data is a reasonable initial value for dist. Anyway, I do no get the logic, as other initial values (such as an array of zeros) bring back the problem of not sampling alpha and beta again.

SketchUp entities mirrored with "flip along (axis)" not reflected in transform matrix

Question updates at the bottom....
I'm writing a custom SketchUp export plugin in Ruby. I then recreate the geometry in Three.js using the exported data.
I'm having troubles with some component/group transformations, and tracked it down to mirroring, or geometry that has "flip along" applied for some axis. Simply put, the flip along is not respected. I can not find any SU Ruby method to find out whether any given entity has this flip along applied.
I can get a transformation matrix, and convert it (see this question of mine how), however it does not work for these flipped objects. Here's an example result; the rest of the model is fine, but the boat is obviously created using flipped boat halves, and in this picture they appear all over the place:
How can I properly take these flipped geometries into account? Do they have some kind of separate matrix, or entity flag in SU Ruby?
Note 1) I have observed similar buggy behaviour in the built-in SketchUp Collada exporter (when loading them with Three.js ColladaLoader).
Note 2) Although I believe this to be a SketchUp Ruby API issue, I tagged this with Three.js just in case there is something obvious I'm missing in regards to mirroring and Matrixes..
Note 3) If the geometries are flipped / mirrored using the scale tool instead of flip along tool (effectively the same result), they work correctly.
UPDATE:
Still struggling to apply this information, but getting closer based on this information: http://sketchucation.com/forums/viewtopic.php?f=6&t=3083
UPDATE #2:
Thanks to Thomthom, I was able to detect and apply correct flipping for objects that are not rotated. For a plain unrotated/unscaled/unflipped component the matrix is:
1.0, 0.0, 0.0
0.0, 1.0, 0.0
0.0, 0.0, 1.0
For a flipped (mirrored) component the matrix can be:
-1.0, 0.0, 0.0
0.0, 1.0, 0.0
0.0, 0.0, 1.0
So I can detect that flip easily and all is fine.
But if I arbitrarily rotate the same component (unflipped) an a couple of axes, the matrix looks like this:
-0.33, -0.58, 0,74
0.87, -0.50, 0,00
0.37, 0.64, 0,67
This works correctly in my exporter/importer, I can reapply this matrix on Three.js side.
But when that already rotated component is also mirrored, the matrix looks like this:
0.33, 0.58, -0.74
0.87, -0.50, 0.00
0.37, 0.64, 0.67
I can't get this matrix work correctly in Three.js, and the component is never mirrored, resulting in the behaviour that can be seen in the picture.
So, I'm not sure what to do. I was able to get correct results by detecting the simpler case (only flipped, not rotated or scaled), then setting for example object.scale.x = object.scale.x * -1; in Three.js for such components. But no solution for items that are both flipped and otherwise rotated or scaled :(
Use my Transformation Inspector to visualize the SketchUp matrix in a 4x4 grid: http://extensions.sketchup.com/en/content/transformation-inspector
Using that I can tell which matrix entry changed as I flipped along any axis:
* **Flip along X:** Index #1
* **Flip along Y:** Index #5
* **Flip along Z:** Index #10
Martin Rinehart has written a breakdown of the transformation in SketchUp: http://www.martinrinehart.com/models/tutorial/tutorial_t.html
Find flipped axis with orientation:
module TransformationHelper
def flipped_x?
dot_x, dot_y, dot_z = axes_dot_products()
dot_x < 0 && flipped?(dot_x, dot_y, dot_z)
end
def flipped_y?
dot_x, dot_y, dot_z = axes_dot_products()
dot_y < 0 && flipped?(dot_x, dot_y, dot_z)
end
def flipped_z?
dot_x, dot_y, dot_z = axes_dot_products()
dot_z < 0 && flipped?(dot_x, dot_y, dot_z)
end
private
def axes_dot_products
[
xaxis.dot(X_AXIS),
yaxis.dot(Y_AXIS),
zaxis.dot(Z_AXIS)
]
end
def flipped?(dot_x, dot_y, dot_z)
dot_x * dot_y * dot_z < 0
end
end
module Example
def self.inspect_flipped
tr = Sketchup.active_model.selection[0].transformation
tr.extend(TransformationHelper)
puts "X Flipped: #{tr.flipped_x?.inspect}"
puts "Y Flipped: #{tr.flipped_y?.inspect}"
puts "Z Flipped: #{tr.flipped_z?.inspect}"
end
end

Spatial Rotation in Gmod Expression2

I'm using expression2 to program behavior in Garry's mod. Expression2 (archive link)
Okay so, to set the precedent. In Gmod I have a block and I am at a complete loss of how to get it to rotate around the 3 up, down and right vectors (Which are local. ie; if I pitch it 45 degrees the forward vector is 0.707, 0.707, 0). Essentially, From the 3 vectors I'd like to be able to get local Pitch/Roll/Yaw. By Local Pitch Roll Yaw I mean that they are completely independent of one another allowing true 3d rotation. So for example; if I place my craft so its nose is parallel to the floor the X,Y,Z would be 0,0,0. If I turn it parallel to the floor (World and Local Yaw) 90 degrees it's now 0, 0, 90. If I then pitch it (World Roll, Local Pitch) it 180 degrees it's now 180, 0, 90. I've already explored quaternions however I don't believe I should post my code here as I think I was re-inventing the wheel.
I know I didn't explain that well but I believe the problem is pretty generic. Any help anyone could offer is greatly appreciated.
Oh, I'd like to avoid gimblelock too.
Essentially calculating the rotation around each of the crafts up/forward/right vectors using the up/forward/right vectors.
To simply the question a generic implementation rather than one specific to Gmod is absolutely fine.
I'm not sure what the application you are looking forward to implementing, however, in this sort of situation, I would usually suggest applying angular force. Would that be sufficient for your needs in this regard?
Well if that is all that you need, then i have managed to perfect the angular force equation to having entities point at a given position.
EntityVector = Entity:massCenter()
Leverage = sqrt( ( Entity:inertia():length()^2 ) / 3 )
LookPos = EntityVector - Target:pos()
A = ang(
toDeg( atanr( LookPos:z() , sqrt( LookPos:x()^2 + LookPos:y()^2) ) ) ,
toDeg( atanr( -LookPos:y(), -LookPos:x() ) ) ,
0 )
EntityAngle = ( ( Entity:angles() - angnorm(A) ) * 5 + Entity:angVel() ) * 5
Entity:applyAngForce( -EntityAngle * Leverage )
This set of equations has helped me through countless projects

Resources