Define a matrix depending on variable in Mathematica - python

I am translating my code from Python to Mathematica. I am trying to define a matrix, whose values depend on a variable chosen by the user, called kappa.
In Python the code looked like that:
def getA(kappa):
matrix = zeros((n, n), float)
for i in range(n):
for j in range(n):
matrix[i][j] = 2*math.cos((2*math.pi/n)*(abs(j-i))*kappa)
n = 5
return matrix
What I have done so far in Mathematica is the following piece of code:
n = 5
getA[kappa_] :=
A = Table[0.0, {n}, {n}];
For[i = 0, i < n, i++,
For[ j = 0, j < n, j++,
A[[i, j]] = 2*Cos[(2*pi/n)*(abs (j - i))*kappa]]];
b = getA[3]
But when I try to evaluate this matrix for a value of kappa equal to 3, I get the following error:
Set::partd: "Part specification A[[i,j]] is longer than depth of object.
How can I fix it?

Try something like this
n = 5;
A = Table[2*Cos[(2 \[Pi]/n) (Abs[ j - i]) \[Kappa]], {i, 1, n}, {j, 1, n}];
b = A /. \[Kappa]->3
I'll leave you to package this into a function if you want to.
You write that you are trying to translate Python into Mathematica; your use of For loops suggests that you are trying to translate to C-in-Mathematica. The first rule of Mathematica club is don't use loops.
Besides that you've made a number of small syntactical errors, such as using abs() where you should have had Abs[] (Mathematica's built-in functions all have names beginning with a capital letter, they wrap their arguments in [ and ], not ( and )), pi is not the name of the value of the ratio of a circle's diameter to its radius (it's called \[Pi]). Note too that I've omitted the multiplication operator which is often not required.

In your particular case, this would be the fastest and the most straightforward solution:
getA[κ_, n_] := ToeplitzMatrix[2 Cos[2 π κ Range[0, n - 1] / n]]

Related

Indexed objects with symmetry in indices

I want to implement/calculate in python the following algebraic expression
the expression
where Sn is the symmetry group of order n (with n an even positive integer) and Delta is a complex function (I will not define this function explicitly in the code, though) that is symmetric in its arguments, i.e.
condition
With the help of sympy, and studing the sample case n=2, so far I have something like the following:
from sympy import *
from itertools import permutations
i, j = symbols('i j', cls=Idx)
Delta = IndexedBase('Delta')
perm = permutations([1, 2])
L = []
for p in list(perm):
L.append(Delta[p[0], p[1]])
print(sum(L))
which yields
Delta[1, 2] + Delta[2, 1]
How can I implement the symmetry condition on the indices of the symbol Delta, so that the answer must be 2*Delta[1, 2]?

How do I implement summation and array iteration correctly based on Pseudo code. PYTHON Relaxation Method

I am trying to implement relaxation iterative solver for a project. The function we create should intake two inputs: Matrix A, and Vector B, and should return iterative vectors X that Approximate solution Ax = b.
Pseudo Code from the book is here:
enter image description here
I am new to Python so I am struggling quite a bit with implementing this method. Here is my code:
def SOR_1(A,b):
k=1
n = len(A)
xo = np.zeros_like(b)
x = np.zeros_like(b)
omega = 1.25
while (k <= N):
for i in range(n-1):
x[i] = (1.0-omega)*xo[i] + (1.0/A[i][i])[omega(-np.sum(A[i][j]*x[j]))
-np.sum(A[i][j]*xo[j] + b[i])]
if ( np.linalg.norm(x - xo) < 1e-9):
print (x)
k = k + 1.0
for i in range(n-1):
xo[i] = x[i]
return x
My question is how do I implement the for loop and generating the arrays correctly based off of the Pseudo Code.
Welcome to Python!
Variables in Python are case sensitive so n is defined but N is not defined. If they are supposed to be different variables, I don't see what your value is for N.
You are off to a good start but the following line is still psuedocode for the most part:
x[i] = (1.0-omega)*xo[i] + (1.0/A[i][i])[omega(-np.sum(A[i][j]*x[j]))
-np.sum(A[i][j]*xo[j] + b[i])]
In the textbook's pseudocode square brackets are being used as a grouping symbol but in Python, they are reserved for creating and accessing lists (which is what python calls arrays). Also, there is no implicit multiplication in Python so you have to write things like (1 + 2)*(3*(4+5)) rather than (1 + 2)[3(4+5)]
The other major issue is that you don't define j. You probably need a for loop that would either look like:
for j in range(1, i):
or if you want to do it inline
sum(A[i][j]*x[j] for j in range(1, i))
Note that range has two arguments, where to start and what value to stop before so range(1, i) is equivalent to the summation from 1 to i - 1
I think you are struggling with that line because there's far too much going on in that line. See if you can figure out parts of it using separate variables or offload some of the work to separate functions.
something like: x[i] =a + b * c * d() - e() but give a,b c, d and e meaningful names. You'd then have to correctly set each variable and define each function but at least you are trying to solve separate problems rather than one huge complex one.
Also, make sure you have your tabs correct. k = k + 1.0 should not be inside that for loop, just inside the while loop.
Coding is an iterative process. First get the while loop working. Don't try to do anything in it (except print out the variable so you can see that it is working). Next get the for loop working inside the while loop (again, just printing the variables). Next get (1.0-omega)*xo[i] working. Along the way, you'll discover and solve issues such as (1.0-omega)*xo[i] will evaluate to 0 because xo is a NumPy list initiated with all zeros.
You'd start with something like:
k = 1
N = 3
n = 3
xo = [1, 2, 3]
while (k <= N):
for i in range(n):
print(k, i)
omega = 1.25
print((1.0-omega)*xo[i])
k += 1
And slowly work more and more of the relaxation solver in until you have everything working.

What exactly are indexed objects in sympy?

I don't understand what indexed objects in sympy are for. The documentation didn't help me understand the concept much.
For instance :
>>> from sympy import symbols, IndexedBase, Idx
>>> M = IndexedBase('M')
>>> i, j = symbols('i j', cls=Idx)
>>> M[i, j]
M[i, j]
What does this code do? What is M[i,j]?
All I understand is that an indexed object gives indices to individual sympy symbols .
I'm looking for a better explanation of indexed objects , along with it's relation to IndexedBase and idx
One-line explanation: they represent a symbolic array of undetermined, possibly infinite, size.
Suppose you want to work with n symbols, how would you do that? Easy enough if n is a given number, like 10. But it's just n, an unspecified integer number. Formulas like that appear in mathematics all the time: "add or multiply (something) over the indices i=1, ..., n".
For example, suppose I have a function in n-dimensional space Rn, such as f(x) = 1/distance(x, 0). The distance is, of course, the square root of the sum of squares of coordinates. And maybe I want to find some partial derivative of f. How to express all of this in SymPy? Like this:
from sympy import *
x = IndexedBase('x')
j, k, n = symbols('j k n', cls=Idx)
f = 1/sqrt(Sum(x[k]**2, (k, 1, n)))
print(f.diff(x[j]))
This computes the derivative of f with respect to the coordinate x[j]. The answer is
-Sum(2*KroneckerDelta(j, k)*x[k], (k, 1, n))/(2*Sum(x[k]**2, (k, 1, n))**(3/2))
which is correct (although perhaps the numerator could be simplified if we assume that j is in the range 1..n).
In the above example, x[j] is the coordinate with index j. In your example, M[i, j] could be the entry of some matrix at position i, j.
M is the name of symbolic array, its class is IndexedBase
i and j are indices of that array, their class is Idx
The above are the classes that you would instantiate yourself. The class of M[i, j] is Indexed but you don't create those objects by using class name, M[i, j] simply does that.
Two recent questions with examples of working with indexed objects:
Create an unknown number of programmatically defined variables
Sum of partial derivatives of a product over a symbolic number of variables
Indexed is primarily used for two use-cases:
Formulas with symbolic subscripts. For example, \sum_{i=1}^n a_i. You could just use Symbol('a_i'), but them the i is not symbolic and in any way related to Symbol('i'). So for instance, Sum(a_i, (i, 1, n)) will just give you n*a_i. Instead IndexedBase('a')[i] represents a different symbol for every value of i, and Sum(IndexedBase('a')[i], (i, 1, n)) effectively represents the above summation.
N-d arrays. This is especially useful for code generation, because the SymPy code printers for languages like C or Fortran will print Indexed objects as array lookups automatically, for instance
>>> a = IndexedBase('a')
>>> i = Idx('i', (1, n))
>>> ccode(a[i])
'a[i]'
>>> fcode(a[i])
' a(i)'
This makes it very easy to write array-based code symbolically using SymPy and generate fast code that computes it.

Defining a range of symbols whose bounds are OTHER symbols

I'm trying to express a summation over an arbitrary (but finite) number of symbols, which I wish to be given by another symbol. For instance, is it possible to say:
N,ci,cj = symbols('N,c_i,c_j')
# pseudocode
k = sum(ci+cj,(ci,0,N),(cj,0,N))
or, more literally,
k = sum(ci+cj, (ci != cj))
My instinct is that it isn't, but I do wish sympy would implement support for it!
UPDATE
It appears sympy offers provisions for indexed variables. Namely:
x = IndexedBase('x')
i,j = symbols('i j',cls=Idx)
however, the you can an error when attempting:
y = Sum(x[i], (i, 0, 2))
Which is:
ValueError: Invalid limits given: ((i, 1, 5),)
You can use a Function, like x = symbols('x', cls=Function) and x(i). Indexed should also work, but it looks like Sum has a bug that disallows Idx. It works if you just use i = symbols('i'), though.

for-loops in Python modules

I'm writing a function for an implicit scheme for solving a specific differential equation. The function looks like this:
import numpy as np
def scheme(N,T):
y = np.zeros(N+1) # Array for implicit scheme
h = T/N # Step length
for i in range(N):
y[i+1] = y[i] + h*(1+4*y[i])
print y
I save the file and later import it the usual way, but when I run the scheme function, y = [0 ... 0] where ... are N-1 zeros. It seems like the values are lost in the scope of the for-loop.
If I instead write the whole function in the interpreter (which in my case is Spyder), everything works as it should.
Why doesn't it work when importing the function from the module?
h = T/N
is it possible that T and N are both integers and T < N? In that case h = 0 (and y stays all zeros), because it is an integer division (1/2 == 0).
Try to replace this line with
h = 1. * T / N
and see the results.
y[i+1] = y[i] + h*(1+4*y[i])
can be rewritten as
y[i+1] = y[i] + h + 4 * h * y[i]
^^^
which means that for y[i] = 0, the new y[i+1] will be h. If the integer division T/N makes it zero, then it is what you get.
Normally, if you divide two integers in python, you will have also integer rounded towards minus infinity.
So
1/3 == 0
In your example, if T and N are integers and T < N, h will be 0.
If h is 0, then all elements of y will be also 0.
This could be fixed by casting value to float, i.e.
float(1)/3 == 0.333
In your case:
h = float(T)/N
Not familiar with Spyder, but quick look at documentation shows, that it is for scientists.
Maybe this interpreter always uses float division.

Categories