Matrix factorise of vector - wolfram-mathematica

Say I have a vector that looks like this:
1/2 a + 1/3 b
b + c
2a + c
1/3c + 4d
Mathematically this can be factorised into matrix and a vector:
Matrix:
1/2 1/3 0 0
0 1 1 0
2 0 1 0
0 0 1/3 4
Vector:
a
b
c
d
(My apologies for the formatting, perhaps someone could suggest how better to do it?)
Is there any way to get mathematica to do this matrix factorisation? In my specific case the terms are not simple expressions such as "a", "b", "c", "d". But are things indexed by a list, e.g.
W[{3,0,0,0}]
W[{1,1,0,0}]
W[{0,0,1,0}]
Thanks!

Possibly:
x = {1/2 a + 1/3 b,
b + c,
2 a + c,
1/3 c + 4 d};
CoefficientArrays[x, {a, b, c, d}][[2]] // MatrixForm
In the case that you want coefficients for all variables, use the compact form:
CoefficientArrays[x][[2]] // MatrixForm
In the case that you do not want coefficients of all variables, part [[1]] comes into play:
x2 = {1/2 a + 1/3 b + q - y,
b + c + 1/2 r,
2 a + c + 2 y,
1/3 c + 4 d};
CoefficientArrays[x2, {a, b, c, d}][[1]] // Normal
{q - y, r/2, 2 y, 0}
Such that you can reconstruct your expression.

Related

Finding the largest power of a number that divides a factorial in haskell

So I am writing a haskell program to calculate the largest power of a number that divides a factorial.
largestPower :: Int -> Int -> Int
Here largestPower a b has find largest power of b that divides a!.
Now I understand the math behind it, the way to find the answer is to repeatedly divide a (just a) by b, ignore the remainder and finally add all the quotients. So if we have something like
largestPower 10 2
we should get 8 because 10/2=5/2=2/2=1 and we add 5+2+1=8
However, I am unable to figure out how to implement this as a function, do I use arrays or just a simple recursive function.
I am gravitating towards it being just a normal function, though I guess it can be done by storing quotients in an array and adding them.
Recursion without an accumulator
You can simply write a recursive algorithm and sum up the result of each call. Here we have two cases:
a is less than b, in which case the largest power is 0. So:
largestPower a b | a < b = 0
a is greater than or equal to b, in that case we divide a by b, calculate largestPower for that division, and add the division to the result. Like:
| otherwise = d + largestPower d b
where d = (div a b)
Or putting it together:
largestPower a b | a < b = 1
| otherwise = d + largestPower d b
where d = (div a b)
Recursion with an accumuator
You can also use recursion with an accumulator: a variable you pass through the recursion, and update accordingly. At the end, you return that accumulator (or a function called on that accumulator).
Here the accumulator would of course be the running product of divisions, so:
largestPower = largestPower' 0
So we will define a function largestPower' (mind the accent) with an accumulator as first argument that is initialized as 1.
Now in the recursion, there are two cases:
a is less than b, we simply return the accumulator:
largestPower' r a b | a < b = r
otherwise we multiply our accumulator with b, and pass the division to the largestPower' with a recursive call:
| otherwise = largestPower' (d+r) d b
where d = (div a b)
Or the full version:
largestPower = largestPower' 1
largestPower' r a b | a < b = r
| otherwise = largestPower' (d+r) d b
where d = (div a b)
Naive correct algorithm
The algorithm is not correct. A "naive" algorithm would be to simply divide every item and keep decrementing until you reach 1, like:
largestPower 1 _ = 0
largestPower a b = sumPower a + largestPower (a-1) b
where sumPower n | n `mod` b == 0 = 1 + sumPower (div n b)
| otherwise = 0
So this means that for the largestPower 4 2, this can be written as:
largestPower 4 2 = sumPower 4 + sumPower 3 + sumPower 2
and:
sumPower 4 = 1 + sumPower 2
= 1 + 1 + sumPower 1
= 1 + 1 + 0
= 2
sumPower 3 = 0
sumPower 2 = 1 + sumPower 1
= 1 + 0
= 1
So 3.
The algorithm as stated can be implemented quite simply:
largestPower :: Int -> Int -> Int
largestPower 0 b = 0
largestPower a b = d + largestPower d b where d = a `div` b
However, the algorithm is not correct for composite b. For example, largestPower 10 6 with this algorithm yields 1, but in fact the correct answer is 4. The problem is that this algorithm ignores multiples of 2 and 3 that are not multiples of 6. How you fix the algorithm is a completely separate question, though.

Find the optimal way to use combinations of summands to get the most sum with a limited number of summands

I have a bit of a problem, I have a set of sums that add up to X, like so:
A: i + j + k = X
B: t + z = X
C: z + z = X
D: j + j + k + k = X
These sums can be more or less, I give 4 here but there could be N of them.
I have a limited number of summands so for example I have
12 of i, 35 of z, 12 of j, and 18 of k, 21 of t
what I need is an algorithm that will determine the best way to use those combinations so that I end up with the most complete sums of X
so in the example above using:
17 of combination C, 1 of combination B, and 12 of combination A, total 30 sums of X, 72 summands used
is worse then using:
21 of combination B, 7 of combination C, and 6 of combination D, total 34 sums of X, 80 summands used
Edit:
To further explain
using 21 of combination B will "spend" 21 t and 21 z leaving us with: 12 of i, 14 of z, 12 of j, 18 of k, 0 of t
using 7 of combination C will "spend" 14 of z (because it uses 2 summands of z to be achieved) leaving us with: 12 of i, 0 of z, 12 of j, 18 of k, 0 of t
using 6 of combination D will spend 12 of j and 12 of k (because it uses both of them twice) leaving us with: 12 of i, 0 of z, 0 of j, 6 of k, 0 of t
we can no longer make combinations that will add up to X thus the algorithm is concluded.
I wrote a program to brute force this problem.
Which for your example data as the best possible combination gives:
1 of combination A, 19 of combination B, and 7 of combination C, 5 of
combination D, total 32 sums of X, 75 summands used
The code as it is although its not that neat and possibly not correct:
# Consider encoding the states
#{i,j,k}
#{i,z}
#{z,z}
#{j,j,k,k}
#as
# i z j k
limits = (21, 35, 12, 18)
sets = [(1,0,1,1), #
(1,1,0,0), #
(0,2,0,0), #
(0,0,2,2), #
]
from heapq import heappush, heappop
def sub(A,B): return tuple(x - y for x,y in zip(A,B))
H = [(0,limits,[0]*len(sets))]
B = []
#X = 0
while H:
#X += 1
C, available, counts = heappop(H)
#if X%1000 == 0:
#print C, available, counts
if not any(all(not x > 0 for x in sub(available, s)) for s in sets):
E = -C, sum(available), available, counts
if E not in B:
#print "found:", E
if len(B) > 0:
#print "best:", B[0]
pass
heappush(B, E)
for i,s in enumerate(sets):
diff = sub(available, s)
if all(x > 0 for x in diff):
counts_ = counts[:]
counts_[i] += 1
E = (C+1, diff, counts_)
if E not in H:
heappush(H, E)
a,b,c,d = heappop(B)
print "%u of combination A, %u of combination B, and %u of combination C, %u of combination D, total %u sums of X, %u summands used" % tuple(d+[-a, sum(limits)-sum(c)])
EDIT:
After entering the revisied problem into this program it produces in 9 seconds:
11 of combination A, 20 of combination B, and 7 of combination C, 0 of
combination D, total 38 sums of X, 87 summands used
The encoding of the revised problem:
# i z j k t
limits = (12,35,12,18,21)
sets = [(1,0,1,1,0), # {i,j,k}
(0,1,0,0,1), # {t,z}
(0,2,0,0,0), # {z,z}
(0,0,2,2,0), # {j,j,k,k}
]

Solve Equations from Equations Mathematica

Well, I need a way to solve equations by another var got from other equation in Mathematica 8. Example:
a + b = 2c
c + 2 = d
d = 2b
It will chose the best equation for the given values and solve the rest.
With some given values, like a = 1 and c = 3, it solves the system, getting the values for the respective variable.
*Will use this for physics' formulas.
Use the Solve or Reduce functions. The syntax is
Solve[{LIST OF EQUATIONS}, {Variables to solve for}]
So in this case:
Solve[{a + b == 2 c, c + 2 == d, d == 2 b}, {a, b, c, d}]
(*->
{{a -> -4 + (3 d)/2, b -> d/2, c -> -2 + d}}
*)
There are 4 variables and only 3 equations, so there are infinite solutions.
They lie on the 4-d line (-4 + (3 n)/2, n/2, n-2, n).

Simplify Absolute Value in Mathematica

I currently have a large expression with many terms of the form
Abs[-2 b + 2 d1 m + l Tan[\[Theta]]]
I know, from the geometry of my problem, that
-2 b + 2 d1 m + l Tan[\[Theta]] > 0
However, when I try to simplify my expression,
Simplify[Abs[-2 b + 2 d1 m + l Tan[\[Theta]]], -2 b + 2 d1 m + l Tan[\[Theta]] > 0]
I just get back
Abs[-2 b + 2 d1 m + l Tan[\[Theta]]]
How can I make Mathematica simplify out the unnecessary absolute value?
EDIT 1
The full expression which I'm trying to simplify is
-(1/(2 (m - Tan[\[Theta]])))
Sqrt[1 + m^2] (B2 Sqrt[(-2 b + 2 d1 m + l Tan[\[Theta]])^2] +
B4 Sqrt[(-2 b + 2 d2 m + l Tan[\[Theta]])^2] +
B5 Sqrt[(2 b + 2 d3 m + l Tan[\[Theta]])^2] +
B7 Sqrt[(2 b + 2 d4 m + l Tan[\[Theta]])^2] +
B1 Sqrt[(2 b - 2 (d1 + l) m + l Tan[\[Theta]])^2] +
B3 Sqrt[(2 b - 2 (d2 + l) m + l Tan[\[Theta]])^2] +
B6 Sqrt[(-2 (b + (d3 + l) m) + l Tan[\[Theta]])^2] +
B8 Sqrt[(-2 (b + (d4 + l) m) + l Tan[\[Theta]])^2])
The terms being squared under each of the radicals is known to be a positive real number.
Since the terms are all known to be real and positive, squaring and taking the square-root will only give you the same number. Hence, you could do something like
expr /. Sqrt[(x___)^2] :> x
where expr is your giant expression above.
Here are two ideas:
1)
Simplify[Abs[-2 b + 2 d1 m + l Tan[\[Theta]]],
0 < \[Theta] < \[Pi]/2 && l > 0 && 2 d1 m > 0 && -2 b > 0]
2)
f[e_] := 100 Count[e, _Abs, {0, Infinity}] + LeafCount[e]
Simplify[Abs[-2 b + 2 d1 m + l Tan[\[Theta]]], -2 b + 2 d1 m +
l Tan[\[Theta]] > 0, ComplexityFunction -> f]
Th complexity function f makes Abs more expensive than Times. See docu for Simplify. Does that help?
If you only wish to remove specific instances of absolute value, you could do something along these lines:
Clear[removeAbs]
removeAbs[expr_, r_] := expr /. {Sqrt[r^2] :> r, Abs[r] :> r}
That way it only removes the absolute value from any expressions you specify:
In: removeAbs[Abs[x] + Abs[y], x]
Out: x + Abs[y]
I'll see if I can find a nicer looking solution than this.
I'm constantly stimied by things like Abs[a]^2, and stuff like using Assuming with a\[Element]Reals doesn't help.
I found some help here WolframMathWorld - Absolute Square with ComplexExpand[Abs[a]^2, TargetFunctions -> {Conjugate}], but sometimes it still returns stuff like Conjugate[Sqrt[a^2 + b^2]] and I've found wrapping a second ComplexExpand (without parameters) around that helps.

How to decompose an integer in two for grid creation

Given an integer N I want to find two integers A and B that satisfy A × B ≥ N with the following conditions:
The difference between A × B and N is as low as possible.
The difference between A and B is as low as possible (to approach a square).
Example: 23. Possible solutions 3 × 8, 6 × 4, 5 × 5. 6 × 4 is the best since it leaves just one empty space in the grid and is "less" rectangular than 3 × 8.
Another example: 21. Solutions 3 × 7 and 4 × 6. 3 × 7 is the desired one.
A brute force solution is easy. I would like to see if a clever solution is possible.
Easy.
In pseudocode
a = b = floor(sqrt(N))
if (a * b >= N) return (a, b)
a += 1
if (a * b >= N) return (a, b)
return (a, b+1)
and it will always terminate, the distance between a and b at most only 1.
It will be much harder if you relax second constraint, but that's another question.
Edit: as it seems that the first condition is more important, you have to attack the problem
a bit differently. You have to specify some method to measure the badness of not being square enough = 2nd condition, because even prime numbers can be factorized as 1*number, and we fulfill the first condition. Assume we have a badness function (say a >= b && a <= 2 * b), then factorize N and try different combinations to find best one. If there aren't any good enough, try with N+1 and so on.
Edit2: after thinking a bit more I come with this solution, in Python:
from math import sqrt
def isok(a, b):
"""accept difference of five - 2nd rule"""
return a <= b + 5
def improve(a, b, N):
"""improve result:
if a == b:
(a+1)*(b-1) = a^2 - 1 < a*a
otherwise (a - 1 >= b as a is always larger)
(a+1)*(b-1) = a*b - a + b - 1 =< a*b
On each iteration new a*b will be less,
continue until we can, or 2nd condition is still met
"""
while (a+1) * (b-1) >= N and isok(a+1, b-1):
a, b = a + 1, b - 1
return (a, b)
def decomposite(N):
a = int(sqrt(N))
b = a
# N is square, result is ok
if a * b >= N:
return (a, b)
a += 1
if a * b >= N:
return improve(a, b, N)
return improve(a, b+1, N)
def test(N):
(a, b) = decomposite(N)
print "%d decomposed as %d * %d = %d" % (N, a, b, a*b)
[test(x) for x in [99, 100, 101, 20, 21, 22, 23]]
which outputs
99 decomposed as 11 * 9 = 99
100 decomposed as 10 * 10 = 100
101 decomposed as 13 * 8 = 104
20 decomposed as 5 * 4 = 20
21 decomposed as 7 * 3 = 21
22 decomposed as 6 * 4 = 24
23 decomposed as 6 * 4 = 24
I think this may work (your conditions are somewhat ambiguous). this solution is somewhat similar to other one, in basically produces rectangular matrix which is almost square.
you may need to prove that A+2 is not optimal condition
A0 = B0 = ceil (sqrt N)
A1 = A0+1
B1 = B0-1
if A0*B0-N > A1*B1-N: return (A1,B1)
return (A0,B0)
this is solution if first condition is dominant (and second condition is not used)
A0 = B0 = ceil (sqrt N)
if A0*B0==N: return (A0,B0)
return (N,1)
Other conditions variations will be in between
A = B = ceil (sqrt N)

Resources