I want to recreate a solve function(solve Ax = b for x) for sparse matrix.
In the Julia documentation, it says that when we applied a sparse matrix to lufact(), it returns the following:
L, U, p, q, Rs = F[:(:)]
With the given formula in Julia doc: LU = Rs.*A[p,q], I did some algebra and obtained the following formula:
x = U \ ( L \ (Rs.*b[p]) )
ipermute!(x,q)
This formula matched with the default F\b solver in Julia when the matrix is dense but the result is off when the matrix is sparse. Does anyone know why?
using LinearAlgebra, then B = lu(A); B\b. Julia returns a type and its dispatch on \ handles the rest.
Related
I would like to solve problems combining boolean and integer logic in linear arithmetic with a SAT/SMT solver. At first glance, Z3 seems promising.
First of all, is it at all possible to solve the following problem? This answer makes it seem like it works.
int x,y,z
boolean a,b,c
( (3x + y - 2z >= 10) OR (A AND (NOT B OR C)) OR ((A == C) AND (x + y >= 5)) )
If so, how does Z3 solve this kind of problem in theory and is there any documentation about it?
I could think of two ways to solve this problem. One would be to convert the Boolean operations into a linear integer expression. Another solution I read about is to use the Nelson-Oppen Combination Method described in [Kro 08].
I found a corresponding documentation in chapter 3.2.2. Solving Arithmetical Fragments, Table 1 a listing of the implemented algorithms for a certain logic.
Yes, SMT solvers are quite good at solving problems of this sort. Your problem can be expressed using z3's Python interface like this:
from z3 import *
x, y, z = Ints('x y z')
A, B, C = Bools('A B C')
solve (Or(3*x + y - 2*z >= 10
, And(A, Or(Not(B), C))
, And(A == C, x + y >= 5)))
This prints:
[A = True, z = 3, y = 0, B = True, C = True, x = 5]
giving you a (not necessarily "the") model that satisfies your constraints.
SMT solvers can deal with integers, machine words (i.e., bit-vectors), reals, along with many other data types, and there are efficient procedures for combinations of linear-integer-arithmetic, booleans, uninterpreted-functions, bit-vectors amongst many others.
See http://smtlib.cs.uiowa.edu for many resources on SMT solving, including references to other work. Any given solver (i.e., z3, yices, cvc etc.) will be a collection of various algorithms, heuristics and tactics. It's hard to compare them directly as each shine in their own way for certain sublogics, but for the base set of linear-integer arithmetic, booleans, and bit-vectors, they should all perform fairly well. Looks like you already found some good references, so you can do further reading as necessary; though for most end users it's neither necessary nor that important to know how an SMT solver internally works.
I'm getting a TypeError with nsolve when I give it a Matrix for the starting vector. Notably, nsolve is perfectly fine with the fact that the equation is a Matrix expression. Here's a basic example:
import sympy as sy
v = sy.Matrix(sy.symarray("v", (2,)))
w = sy.Matrix([17, 23])
equation = v - w
The following line gives a TypeError: cannot create mpf from Matrix([[17],[23]]):
sy.nsolve(equation, v, w)
The following line is a kludgy workaround which gives the correct output, Matrix([[17.0],[23.0]]):
sy.nsolve(equation, v, w.T.tolist()[0])
Is there a better solution than this workaround?
The workaround you have is necessary, given the following:
nsolve passes the x0 argument directly to mpmath.findroot, on this line
findroot only supports iterables in x0 that satisfy isinstance(x0, (list, tuple)), on this line. Moreover it has to be a flat tuple or list; its elements are assumed to be scalars in the subsequent x0 = [ctx.convert(x) for x in x0].
A SymPy matrix is not an instance of either list or tuple. Also, w.tolist() is not enough because the resulting list is nested. Hence the need for w.T.tolist()[0].
This is now an open issue in SymPy repo.
In chapter 1 on fixed points, the book says we can find fixed points of certain functions using
f(x) = f(f(x)) = f(f(f(x))) ....
What are those functions?
It doesn't work for y = 2y when i rewrite it as y = y/2 it works
Does y need to get smaller everytime? Or are there any general attributes that a function has to have to find fixed points by that method?
What conditions it should satisfy to work?
According to the Banach fixed-point theorem, such a point exists iff the mapping (function) is a contraction. That means that, for example, y=2x doesn't have fixed point and y = 0,999... * x has. In general, if f maps [a,b] to [a,b], then |f(x) - f(y)| should be equal to c * |x - y| for some 0 <= c < 1 (for all x, y from [a, b]).
Say you have:
f(x) = sin(x)
then x = 0 is a fixed point of the function since:
f(0) = sin(0) = 0
f(f(0)) = sin(sin(0)) = sin(0) = 0
Not every point along x is a fixed point of sin, only 0 is.
Different functions have different fixed points, if at all. You can find more on fixed points of functions at Wikidpedia
I hope this hasn't been asked before, if so I apologize.
EDIT: For clarity, the following notation will be used: boldface uppercase for matrices, boldface lowercase for vectors, and italics for scalars.
Suppose x0 is a vector, A and B are matrix functions, and f is a vector function.
I'm looking for the best way to do the following iteration scheme in Mathematica:
A0 = A(x0), B0=B(x0), f0 = f(x0)
x1 = Inverse(A0)(B0.x0 + f0)
A1 = A(x1), B1=B(x1), f1 = f(x1)
x2 = Inverse(A1)(B1.x1 + f1)
...
I know that a for-loop can do the trick, but I'm not quite familiar with Mathematica, and I'm concerned that this is the most efficient way to do it. This is a justified concern as I would like to define a function u(N):=xNand use it in further calculations.
I guess my questions are:
What's the most efficient way to program the scheme?
Is RecurrenceTable a way to go?
EDIT
It was a bit more complicated than I tought. I'm providing more details in order to obtain a more thorough response.
Before doing the recurrence, I'm having problems understanding how to program the functions A, B and f.
Matrices A and B are functions of the time step dt = 1/T and the space step dx = 1/M, where T and M are the number of points in the {0 < x < 1, 0 < t} region. This is also true for vector the function f.
The dependance of A, B and f on x is rather tricky:
A and B are upper and lower triangular matrices (like a tridiagonal matrix; I suppose we can call them multidiagonal), with defined constant values on their diagonals.
Given a point 0 < xs < 1, I need to determine it's representative xn in the mesh (the closest), and then substitute the nth row of A and B with the function v( x) (transposed, of course), and the nth row of f with the function w( x).
Summarizing, A = A(dt, dx, xs, x). The same is true for B and f.
Then I need do the loop mentioned above, to define u( x) = step[T].
Hope I've explained myself.
I'm not sure if it's the best method, but I'd just use plain old memoization. You can represent an individual step as
xstep[x_] := Inverse[A[x]](B[x].x + f[x])
and then
u[0] = x0
u[n_] := u[n] = xstep[u[n-1]]
If you know how many values you need in advance, and it's advantageous to precompute them all for some reason (e.g. you want to open a file, use its contents to calculate xN, and then free the memory), you could use NestList. Instead of the previous two lines, you'd do
xlist = NestList[xstep, x0, 10];
u[n_] := xlist[[n]]
This will break if n > 10, of course (obviously, change 10 to suit your actual requirements).
Of course, it may be worth looking at your specific functions to see if you can make some algebraic simplifications.
I would probably write a function that accepts A0, B0, x0, and f0, and then returns A1, B1, x1, and f1 - say
step[A0_?MatrixQ, B0_?MatrixQ, x0_?VectorQ, f0_?VectorQ] := Module[...]
I would then Nest that function. It's hard to be more precise without more precise information.
Also, if your procedure is numerical, then you certainly don't want to compute Inverse[A0], as this is not a numerically stable operation. Rather, you should write
A0.x1 == B0.x0+f0
and then use a numerically stable solver to find x1. Of course, Mathematica's LinearSolve provides such an algorithm.
Currently I use a single equation with different combination of known/unknown parameters. As I don't have any fancy calculator it would be much easier to define the equation in Mathematica and passing known parameters to calculate unknown values.
I would be very thankful if anyone of you could give an example solution (if possible using given equation).
Let's say we have an equation of satellite speed at given point in the elliptical orbit:
v = sqrt(u(2/r - 1/a))
where
v = speed
u = constant 3.986 * 10^14 m^3/s^2
r = radius (distance from the center of the Earth)
a = semi major axis of the ellipse
This equation can be used to calculate the speed or for example we know what is the speed needed for a manoeuvre to move the cargo to other orbit and have to model the orbit (a) at given radius (r)
Thanks!
You can define equations in Mathematica using the ":=" operator. To define the example equation:
v[u_, r_, a_] := Sqrt[u*(2/r-1/a)]
I'm not sure how to generalize it to solve for any unknown...If I figure it out I'll get back to you.
You may want to try something like:
Solve[v[1, r, 7]==15, r]
that will solve for r assuming you know v, u, and a... you can then change each of the paramaters for the unknown...
A little bit late :) ... but Reduce[] does what you want. We define a function:
solveForMe[rules_] := Reduce[( v == Sqrt[3.986*10^14 *(2/r - 1/a)]) /. rules];
and invoke it with any valid combination for the assignments. For example:
In[72]:= Off[Reduce::ratnz];
solveForMe[{a -> 7 10^6, r -> 7 10^6}]
solveForMe[{v -> 10, r -> 7 10^6}]
solveForMe[{v -> 10, a -> 7 10^6}]
The output is :
Out[73]= v == 7546.05
Out[74]= a == 3.5*10^6
Out[75]= r == 1.4*10^7
HTH! ...