Skip to content

Commit

Permalink
add bring_power_down = FALSE to deriv; normalize_coefficients()
Browse files Browse the repository at this point in the history
  • Loading branch information
dkahle committed Jun 15, 2023
1 parent 7e8a96d commit 6b4c1f2
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 20 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: mpoly
Type: Package
Title: Symbolic Computation and More with Multivariate Polynomials
Version: 1.1.1.901
Version: 1.1.1.902
URL: https://github.com/dkahle/mpoly
BugReports: https://github.com/dkahle/mpoly/issues
Authors@R: person("David", "Kahle", email = "david@kahle.io", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-9999-1558"))
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export(mp)
export(mpoly)
export(mpolyList)
export(multideg)
export(normalize_coefficients)
export(partitions)
export(permutations)
export(plug)
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

* `coef()` allows you to extract the coefficients of an mpoly object (#25,
thanks @ggrothendieck).

* `deriv()` now allows you to not bring the power down as a multiplier.

* `normalize_coefficients()` now allows you normalize term coefficients
according to an input norm, defaulting to the Euclidean norm.



Expand Down
28 changes: 28 additions & 0 deletions R/components.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#' @param object mpoly object to pass to [coef()]
#' @param ... In [coef()], additional arguments passed to [print.mpoly()] for
#' the names of the resulting vector
#' @param p an object of class mpoly or mpolyList
#' @param norm a norm (function) to normalize the coefficients of a polynomial,
#' defaults to the Euclidean norm
#' @return An object of class mpoly or mpolyList, depending on the context
#' @name components
#' @examples
Expand All @@ -35,6 +38,18 @@
#'
#' homogeneous_components(p)
#'
#' (p <- mp("(x + y)^2"))
#' normalize_coefficients(p)
#' norm <- function(v) sqrt(sum(v^2))
#' norm(coef( normalize_coefficients(p) ))
#'
#' abs_norm <- function(x) sum(abs(x))
#' normalize_coefficients(p, norm = abs_norm)
#'
#' p <- mp(c("x", "2 y"))
#' normalize_coefficients(p)
#'
#'



Expand Down Expand Up @@ -174,3 +189,16 @@ coef.mpoly <- function(object, ...) {





#' @rdname components
#' @export
normalize_coefficients <- function(p, norm = function(x) sqrt(sum(x^2))) {
if (is.mpolyList(p)) return( structure(lapply(p, normalize_coefficients), class = "mpolyList") )
normalize <- function(x) x / norm(x)
c <- normalize(coef(p))
for (i in seq_along(p)) p[[i]]["coef"] <- c[i]
p
}


27 changes: 17 additions & 10 deletions R/deriv.mpoly.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@
#' @param expr an object of class mpoly
#' @param var character - the partial derivative desired
#' @param ... any additional arguments
#' @param bring_power_down if `FALSE`, x^n -> x^(n-1), not n x^(n-1)
#' @return An object of class mpoly or mpolyList.
#' @export
#' @examples
#' m <- mp("x y + y z + z^2")
#' deriv(m, "x")
#' deriv(m, "y")
#' deriv(m, "z")
#' deriv(m, c("x","y","z"))
#' deriv(m, "a")
#' is.mpoly(deriv(m, "x"))
#' is.mpolyList( deriv(m, c("x","y","z")) )
deriv.mpoly <- function(expr, var, ...){
#' p <- mp("x y + y z + z^2")
#' deriv(p, "x")
#' deriv(p, "y")
#' deriv(p, "z")
#' deriv(p, "t")
#' deriv(p, c("x","y","z"))
#'
#' is.mpoly(deriv(p, "x"))
#' is.mpolyList( deriv(p, c("x","y","z")) )
#'
#' p <- mp("x^5")
#' deriv(p, "x")
#' deriv(p, "x", bring_power_down = FALSE)
#'
deriv.mpoly <- function(expr, var, ..., bring_power_down = TRUE){

# argument checks
if (missing(var)) stop("var must be specified, see ?deriv.mpoly", call. = FALSE)
Expand Down Expand Up @@ -46,7 +53,7 @@ deriv.mpoly <- function(expr, var, ...){
if(length(v) == 1) return(c(coef = 0))
p <- length(v)
if(!(var %in% names(v[1:p]))) return(c(coef = 0))
v["coef"] <- unname(v[var]) * v["coef"]
if (bring_power_down) v["coef"] <- unname(v[var]) * v["coef"]
v[var] <- v[var] - 1
v
})
Expand Down
20 changes: 20 additions & 0 deletions man/components.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 17 additions & 9 deletions man/deriv.mpoly.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions tests/testthat/test-components.R
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,51 @@ test_that("coef works", {





test_that("normalize_coefficients works", {

p <- mp("(x + y)^2")

expect_equal(
normalize_coefficients(p),
structure(
list(
c(x = 2, coef = 0.408248290463863),
c(x = 1, y = 1, coef = 0.816496580927726),
c(y = 2, coef = 0.408248290463863)
),
class = "mpoly"
)
)

abs_norm <- function(x) sum(abs(x))
expect_equal(
normalize_coefficients(p, norm = abs_norm),
structure(
list(
c(x = 2, coef = 0.25),
c(x = 1, y = 1, coef = 0.5),
c(y = 2, coef = 0.25)
),
class = "mpoly"
)
)

expect_equal(
sum(coef(normalize_coefficients(p))^2),
1
)

expect_equal(
normalize_coefficients(mp(c("x", "5 y"))),
mp(c("x", "y"))
)




})



15 changes: 15 additions & 0 deletions tests/testthat/test-deriv.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ test_that("vector indeterminates", {





test_that("bring_down_power works", {

p <- mp("x^5")

expect_equal(
mp("x^4"),
deriv(p, "x", bring_power_down = FALSE)
)

})



test_that("gradient", {

expect_equal(
Expand Down

0 comments on commit 6b4c1f2

Please sign in to comment.