Skip to content

Commit

Permalink
simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
flying-sheep committed Nov 13, 2024
1 parent afefdd7 commit e626e90
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ __pycache__/
/vignettes/*.html
/vignettes/*.R
/vignettes/*_files/
/vignettes/.build.timestamp
1 change: 1 addition & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "linux-clang-x64",
"compilerArgs": ["-Wall"]
},
],
"version": 4,
Expand Down
16 changes: 16 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@
"ylen",
"zlen"
],
"files.associations": {
"*.desktop": "ini",
"vimrc": "viml",
"zshrc": "shellscript",
".zpreztorc": "shellscript",
"zpreztorc": "shellscript",
"asv.conf.json": "jsonc",
"*.tags": "lua",
"*.tikz": "context",
"*.lmtx": "context",
".prettierrc": "jsonc",
"*.yaml": "jinja-yaml",
"*.j2": "jinja-md",
"cmath": "cpp",
"cstddef": "cpp"
},
}
8 changes: 4 additions & 4 deletions R/censoring.r
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ validate_censoring <- function(data, sigma, dists, censor_val, censor_range, mis
stop('You have to provide both a censoring value and a censor_range or none')

if (!is.null(censor_range)) {
if (!is.numeric(censor_val) || (length(censor_val) != 1L && length(censor_val) != g))
stop('censor_val has to be a single numeric value, or length(censor_val) == ncol(data) must be TRUE')
if (!is.numeric(censor_val) || !(length(censor_val) %in% c(g, 1L)))
stop('censor_val has to be a single numeric value, or length(censor_val) == ncol(data) must be TRUE')

if (!is.numeric(censor_range) || !(nrow(censor_range) %in% c(g, 1L)) || ncol(censor_range) != 2L || any(diff(t(censor_range)) <= 0L))
stop('censor_range has to be a numeric vector of length 2, the second of which being larger,
stop('censor_range has to be a numeric vector of length 2, the second of which being larger,
or a matrix with nrow(censor_range) == ncol(data) where each row is such a vector')
}

if (!is.null(missing_range)) {
if (!is.numeric(missing_range) || !(nrow(missing_range) %in% c(g, 1L)) || ncol(missing_range) != 2L || any(diff(t(missing_range)) <= 0L))
stop('missing_range has to be a numeric vector of length 2, the second of which being larger,
stop('missing_range has to be a numeric vector of length 2, the second of which being larger,
or a matrix with nrow(missing_range) == ncol(data) where each row is such a vector')
}

Expand Down
58 changes: 27 additions & 31 deletions src/censoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ inline double censor_pair(
bool use_d;
const bool
one_uncertain = (c == thr) || (d == thr),
one_missing = NumericVector::is_na(c) || NumericVector::is_na(d),
one_of_each_invalid = one_uncertain && one_missing,
both_valid = !one_uncertain && !one_missing;
one_missing = NumericVector::is_na(c) || NumericVector::is_na(d);

/*
Rcout << "one uncertain=" << one_uncertain << " one missing=" << one_missing
Expand All @@ -45,36 +43,34 @@ inline double censor_pair(
// 3. (missing-uncertain): interference of two different box functions
// 4. (invalid×2): two missing or two uncertain => 1

if (both_valid) { //1
if (!one_uncertain && !one_missing) { //1
return exp(-pow(c-d, 2) / (kt*2));
} else { //at least one invalid
if (one_of_each_invalid) { //3
const double uncertain_range = uncertain1 - uncertain0 + 2*sigma;
return uncertain_range / (sqrt(uncertain_range) * sqrt(missing1 - missing0));
} else if (one_uncertain || one_missing) { //2
double m0, m1;
if (one_uncertain && !one_missing) {
m0 = uncertain0;
m1 = uncertain1;
use_d = c == thr;
} else if (!one_uncertain && one_missing) {
m0 = missing0;
m1 = missing1;
use_d = NumericVector::is_na(c);
}

const double v = use_d ? d : c;

return
pow(M_PI*kt/2, -1./4)
* sqrt(M_PI*kt/4)
* ( std::erfc((m0-v) / sigma) - std::erfc((m1-v) / sigma) )
/ sqrt(m1-m0);

//Rcout << "m0=" << m0 << " m1=" << m1 << " use d=" << use_d << " x=" << x << " v=" << v << '\n';
} else {// both are uncertain or both are missing => x *= 1 => noop
return 1;
} else if (one_uncertain && one_missing) { //3
const double uncertain_range = uncertain1 - uncertain0 + 2*sigma;
return uncertain_range / (sqrt(uncertain_range) * sqrt(missing1 - missing0));
} else if (one_uncertain || one_missing) { //2
double m0, m1;
if (one_uncertain && !one_missing) {
m0 = uncertain0;
m1 = uncertain1;
use_d = c == thr;
} else if (!one_uncertain && one_missing) {
m0 = missing0;
m1 = missing1;
use_d = NumericVector::is_na(c);
}

const double v = use_d ? d : c;

return
pow(M_PI*kt/2, -1./4)
* sqrt(M_PI*kt/4)
* ( std::erfc((m0-v) / sigma) - std::erfc((m1-v) / sigma) )
/ sqrt(m1-m0);

//Rcout << "m0=" << m0 << " m1=" << m1 << " use d=" << use_d << " x=" << x << " v=" << v << '\n';
} else {// both are uncertain or both are missing => x *= 1 => noop
return 1;
}
}

Expand Down
11 changes: 5 additions & 6 deletions vignettes/Diffusion-Maps.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,15 @@ plot3d(
type = 's', radius = .01)
view3d(theta = 10, phi = 30, zoom = .8)
# now use your mouse to rotate the plot in the window
rgl.close()
close3d()
```

For the popular `ggplot2` package, there is built in support in the form of a `fortify.DiffusionMap` method, which allows to use DiffusionMap objects as `data` parameter in the `ggplot` and `qplot` functions. But the regular `plot` function already returns a `ggplot` object anyway.

```{r}
library(ggplot2)
qplot(DC1, DC2, data = dm, colour = factor(num_cells)) +
scale_color_cube_helix()
# or alternatively: ggplot(dif, aes(DC1, DC2, colour = factor(num.cells))) + ...
ggplot(dm, aes(DC1, DC2, colour = factor(num_cells))) +
geom_point() + scale_color_cube_helix()
```

As aesthetics, all diffusion components, gene expressions, and annotations are available. If you plan to make many plots, create a `data.frame` first by using `as.data.frame(dif)` or `fortify(dif)`, assign it to a variable name, and use it for plotting.
Expand All @@ -195,8 +194,8 @@ Dimensions `dims`
Diffusion maps consist of the eigenvectors (which we refer to as diffusion components) and corresponding eigenvalues of the diffusion distance matrix. The latter indicate the diffusion components’ importance, i.e. how well the eigenvectors approximate the data. The eigenvectors are decreasingly meaningful.

```{r}
qplot(y = eigenvalues(dm)) + theme_minimal() +
labs(x = 'Diffusion component (DC)', y = 'Eigenvalue')
ggplot(NULL, aes(x = seq_along(eigenvalues(dm)), y = eigenvalues(dm))) + theme_minimal() +
geom_point() + labs(x = 'Diffusion component (DC)', y = 'Eigenvalue')
```

The later DCs often become noisy and less useful:
Expand Down

0 comments on commit e626e90

Please sign in to comment.