Carl Love

Carl Love

28015 Reputation

25 Badges

12 years, 297 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Use add, not sum.

add(add(add(a_(i,j,k)*d(i, j, k), k = 0 .. 1), j = 0 .. 1), i = 0 .. 1);

The reason that it doesn't work with sum is that i, j, and k have the value 1 from some previous computation. Using add, it will ignore previous values of the index variables. But sum---like the vast majority of Maple procedures---evaluates its arguments before they are passed.

f:= n-> a^n + b^n + c^n:
Sol:= {solve({f(1)=1, f(2)=2, f(3)=3}, {a,b,c})}:
nops(Sol);
                               1
evala(eval(f(5), Sol[1]));
                               6

Here's a solution technique that tends to give a large number of zeros in the solutions vector, and a large number of integer entries.

I will assume that your 500x1300 matrix contains floating-point data. If it contains integer data, then you can skip the Integerize step below.

The first is convert the problem to an integer problem by multiplying each row by its least common denominator. The procedure Integerize does that.


Integerize:= proc(AA::Matrix(realcons))
uses LA= LinearAlgebra;
local A:= convert~(AA, rational), k;
     for k to LA:-RowDimension(A) do
          LA:-RowOperation(
               A, k,
               ilcm(map(denom, convert(A[k,..], list))[]),
               inplace
          )
      end do;
      A
end proc:

macro(LA= LinearAlgebra):

(n,m):= (500,1300):

A:= LA:-RandomMatrix(n, m, generator= -1..1., density= 5/n):

B:= Vector([1, 0 $ (n-1)]):

X:= evalf(LA:-Modular:-IntegerLinearSolve(Integerize(< A | B >), m)[1]);

X := Vector(4, {(1) = ` 1 .. 1300 `*Vector[column], (2) = `Data Type: `*anything, (3) = `Storage: `*rectangular, (4) = `Order: `*Fortran_order})

Check solution:

LA:-Norm(A.X - B);

0.

Count nonzero entries in solution vector.

LA:-Dimension(ArrayTools:-SearchArray(X));

14

Show nonzero entries.

seq(X[k], k= ArrayTools:-SearchArray(X));

-1., -1., 1., 1., -1., 1., 1., -1., -1., -1., -1., 1., -1., 1.


Download Integerize.mw

 

This is probably not more efficient or direct, but it does look neater to me and easier to understand:

tmp:= seq(phi[j-1]*~[1-p[j], p[j]], j= 5..2, -1);
Vector(op~([tmp]));

A *~ B

See ?elementwise

It takes several short steps to remove all of Maple's knowledge about gamma. In Maple 16, do these:

restart:
constants:= ({constants} minus {gamma})[]:
`evalf/gamma`:= proc() end proc:
`evalf/constant/gamma`:= proc() end proc:
unprotect(gamma);

Note that this will affect certain special functions, such as Psi, that depend on gamma. The effect will ensue even when those functions are being used (unbeknowst to the user) in the background, rather than being explicitly invoked by the user.

Consider the following plot:

plot([x, 1/3 - (1/3)*x], x= 0..1);

Since the two lines intersect between x=0 and x=1, there is no meaningful way to order the expressions; the is will return false no matter which direction you put the inequality.

 

sys:= {diff(y(t),t) = 2 - t^2/2 - 1/4 * Y(t), diff(Y(t),t)= y(t), Y(0)=0}:
eval(y(t), dsolve(sys, {Y(t), y(t)}));

Here's a crude procedure for it:


restart:

PowerMethod:= proc(
     A::Matrix(square, complexcons),
     {tolerance:= 10^(1-Digits)},
     {maxiterations:= 99},
     $
)
uses LA= LinearAlgebra;
local
     n:= LA:-RowDimension(A),
     b:= Vector(n, fill= 1.),
     T,
     e0:= 0,
     e1
;
     to maxiterations do
          T:= A.b;
          e1:= LA:-Norm(T);
          if abs(e1-e0) < tolerance then  return e1  end if;
          e0:= e1;
          userinfo(2, PowerMethod, e0);
          b:= T/e0
     end do;
     FAIL
end proc:           

 

A:= LinearAlgebra:-RandomMatrix(3, shape= symmetric, datatype= float[8]);

A := Matrix(3, 3, {(1, 1) = 67., (1, 2) = -31., (1, 3) = 92., (2, 1) = -31., (2, 2) = 44., (2, 3) = 29., (3, 1) = 92., (3, 2) = 29., (3, 3) = 99.})

PowerMethod(A);

176.421771487843387

LinearAlgebra:-Eigenvalues(A);

Vector(3, {(1) = -33.5577318719757, (2) = 67.1359603841324, (3) = 176.421771487843})

 


Download PowerMethod.mw

You can do it with LinearAlgebra:-QRDecomposition or LinearAlgebra:-LinearSolve(..., method= QR).

There is some bug here; I don't know specifically where. The bug is manifested regardless of whether there are assumptions.

Here's a workaround: convert to a list and then back to a Vector.

k:= Vector[column]([W, (1/3)*W, (1/3)*W, (1/3)*W]);
Vector(sort(convert(k, list), (a,b)->is(a>b)));

The Power method won't converge for this matrix because there are two eigenvalues with the maximal absolute value.

You should stop using the deprecated linalg package. Everything you need is in LinearAlgebra, for example Eigenvalues and Eigenvectors.

You just have some minor syntax problems:

  1. You need an extra pair of square brackets to enclose the data.
  2. You used two independent variables, x and v, in the curve.

CurveFitting:-LeastSquares(
     [
          [1.0, 2.33], [2.0, 0.626e-1], [3.0, -2.16],
          [4.0, -2.45], [5.0, -.357], [6.0, 2.21],
          [7.0, 2.75], [8.0, .636], [9.0, -2.45]
     ],
     x,
     curve = a+b*cos(x)+c*sin(x)+d*cos(2*x)+e*sin(2*x)
);

Note that this solution does not explicitly use the LinearAlgebra package. It can be modified to use LinearAlgebra:-LeastSquares if that's what you want.

You should stop using the deprecated linalg package in all your code.


restart:

Pts:= [[2,0], [6,1], [8,0]]:

n:= nops(Pts):

V:= [a, b, c]:

f:= unapply(add(V[k]*x^(n-k), k= 1..n), x);

proc (x) options operator, arrow; a*x^2+b*x+c end proc

Eqns:= (p-> f(p[1]) = p[2]) ~ (Pts);

[4*a+2*b+c = 0, 36*a+6*b+c = 1, 64*a+8*b+c = 0]

A:= LinearAlgebra:-GenerateMatrix(Eqns, V, augmented);

A := Matrix(3, 4, {(1, 1) = 4, (1, 2) = 2, (1, 3) = 1, (1, 4) = 0, (2, 1) = 36, (2, 2) = 6, (2, 3) = 1, (2, 4) = 1, (3, 1) = 64, (3, 2) = 8, (3, 3) = 1, (3, 4) = 0})

R:= LinearAlgebra:-ReducedRowEchelonForm(A);

R := Matrix(3, 4, {(1, 1) = 1, (1, 2) = 0, (1, 3) = 0, (1, 4) = -1/8, (2, 1) = 0, (2, 2) = 1, (2, 3) = 0, (2, 4) = 5/4, (3, 1) = 0, (3, 2) = 0, (3, 3) = 1, (3, 4) = -2})

Sol:= convert(V =~ R[..,-1], list);

[a = -1/8, b = 5/4, c = -2]

eval(f(x), Sol);

-(1/8)*x^2+(5/4)*x-2

 


Download Interpolate.mw

I used exact arithmetic in your worksheet, and I got all zeros at the end. To use exact arithmetic, I did three things:

  1. I changed all numbers of the form 210e9 to 210*10^9
  2. I changed all numbers of the form 0.5, 0.25, etc., to 1/2, 1/4, etc.
  3. I removed all evalf.

Luckily, there was no significant increase in the computation time. With these changes, the setting of Digits is insignificant.

Here is the modified worksheet: Exact_arithmetic.mws

 

First 339 340 341 342 343 344 345 Last Page 341 of 394