Matrix multiplication by symbolic vector

22 views
Skip to first unread message

cyrille piatecki

unread,
Jun 6, 2021, 4:47:24 AMJun 6
to sage-support

Hello, usually I ask question by Ask sagemath but the server seems down since yesterday.

I would like to define a matrix function with symbolic variables (Linear or quadratic) of the form x A x,   B x...  and also linear inequalities of the form C x <= b for any size of the A, B and C matrix. The final problem is to optimize or to manipulate equations or inequations.

Whichever be my fails effort, and my reading comfort me, it seems not to be allowed in Sagemath which seems strange. But a recent reading seems to say that

R = PolynomialRing(RR, 'c', 20)
c = R.gens()

could solve my problem. In fact, if I define a list of c[i]

show([c[0],c[1],c[2]]) <-- this work
[c[i] for i in range(0..2)] <-- this doesn't work

I need to understand

Thanks




slelievre

unread,
Jun 6, 2021, 6:14:15 AMJun 6
to sage-support
2021-06-06 10:47:24 UTC+2, Cyrille Piatecki:

>
> [c[i] for i in range(0..2)] <-- this doesn't work

You are mixing two different options:

- range:
  [c[i] for i in range(2)]
  [c[i] for i in range(0, 2)]

- ellipsis:
  [c[i] for i in (0 .. 2)]

cyrille piatecki

unread,
Jun 6, 2021, 8:41:58 AMJun 6
to sage-support
OK, one more time I feel stupid and one more time thanks to answer. But now look at this

R = PolynomialRing(RR, 'c', 20)
c = R.gens()
c=vector([c[i] for i in (0..2)])
Z1=matrix([[1, 2],[3,4]])*vector([c[1],c[2]])
show(Z1)<--- correct display
But c and c[1] is not recognized. So I do not know how to call the c's.
solve(Z1[0]==0,c)

solve(Z1[0]==0,c[1])

slelievre

unread,
Jun 6, 2021, 10:45:22 AMJun 6
to sage-support
Don't feel stupid, but learn from your mistakes.
Go beyond "this works / this doesn't work":

> [c[i] for i in range(0..2)] <-- this doesn't work

Read error messages, they contain useful information.
```
sage: [c[i] for i in range(0..2)]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-...> in <module>
----> 1 [c[i] for i in range(ellipsis_iter(Integer(0),Ellipsis,Integer(2)))]

TypeError: 'generator' object cannot be interpreted as an integer
```
Here, you can see that
- `range(0..2)` was preparsed as
  `range(ellipsis_iter(Integer(0),Ellipsis,Integer(2)))`,
- we get a type error because something (here: range)
  expected an integer and got something else
This gives a clue of what went wrong: range wants
integer arguments: range(2), range(1, 3);  but not
range of an ellipsis iteration like `0 .. 2`.

Now, about the proposed code after fixing this range mistake.

After defining:
```
sage: R = PolynomialRing(RR, 'c', 20)
sage: c = R.gens()
sage: c = vector([c[i] for i in (0 .. 2)])
sage: Z1 = matrix([[1, 2], [3, 4]])*vector([c[1], c[2]])
```
we have:
```
sage: Z1
(c1 + 2.00000000000000*c2, 3.00000000000000*c1 + 4.00000000000000*c2)
sage: Z1[0]
c1 + 2.00000000000000*c2
```

This `Z1[0]` is a polynomial, not a symbolic expression:
```
sage: parent(Z1[0])
Multivariate Polynomial Ring in c0, c1, c2, ..., c18, c19
over Real Field with 53 bits of precision
```

So `== 0` tests whether it is zero:
```
sage: Z1[0] == 0
False
```
and does not give a symbolic equation.

To get an equation, convert `Z1[0]` to the symbolic ring:
```
sage: SR(Z1[0]) == 0
1.00000000000000*c1 + 2.00000000000000*c2 == 0
```

To use `solve`, both the equation and the variable
must be in the symbolic ring.

Converting polynomial variables over the floating-point reals `RR`
to symbolic variables is a little more tricky:
```
sage: SR(c[1])
1.00000000000000*c1
sage: SR(c[1]).variables()[0]
c1
```

From there:
```
sage: solve(SR(Z1[0]) == 0, SR(c[1]).variables()[0])
[c1 == -2*c2]
```

Working over the integers or the rationals simplifies things a bit:
```
sage: R = PolynomialRing(QQ, 'c', 20)
sage: c = vector(R.gens())
sage: c[1:3]
(c1, c2)
sage: Z1 = matrix([[1, 2], [3, 4]])*c[1:3]
sage: Z1
(c1 + 2*c2, 3*c1 + 4*c2)
sage: Z1[0]
c1 + 2*c2
sage: SR(Z1[0])
c1 + 2*c2
sage: SR(c[1])
c1
sage: solve(SR(Z1[0]) == 0, SR(c[1]))
[c1 == -2*c2]
```

Note that for equations of the form `== 0`,
you can skip the `== 0` when calling `solve`,
feeding it only the left hand side:
```
sage: solve(SR(Z1[0]), SR(c[1]))
[c1 == -2*c2]
```

Reply all
Reply to author
Forward
0 new messages