dharr

Dr. David Harrington

8235 Reputation

22 Badges

20 years, 340 days
University of Victoria
Professor or university staff
Victoria, British Columbia, Canada

Social Networks and Content at Maplesoft.com

Maple Application Center
I am a retired professor of chemistry at the University of Victoria, BC, Canada. My research areas are electrochemistry and surface science. I have been a user of Maple since about 1990.

MaplePrimes Activity


These are answers submitted by dharr

Of course the more specific you are about the function h(x) and the initial/boundary condition, the more detailed the solution will be. The help page is found online here.

restart

ode := h(x) = g(x)+(diff(g(x), x))/g(x)

h(x) = g(x)+(diff(g(x), x))/g(x)

dsolve(ode)

g(x) = exp(Int(h(x), x))/(Int(exp(Int(h(x), x)), x)+c__1)

DEtools:-odeadvisor(ode)

[_Bernoulli]

Following gives a help page describing the Bernoulli case and the transformation used to solve it.

DEtools:-odeadvisor(ode, help)


 

Download Bernoulli.mw

Here's my take on the derivatives, since you explicitly asked about D

Download Derivatives.mw

For approximations, you always trade off compactness for accuracy, so I don't see why you don't just plot derivatives. To solve any confusion about which Root is used, you can check with fdiff, which does it by numerical function evaluations of the RootOf. In all the cases here, it is the same as a derivative using D

MaPal93approx.mw

For your directed acyclic graph, the algorithm is relatively simple and can be be done with a compiled Maple routine that runs in a reasonable time (3 min on my old laptop).

Find all paths between two vertices in a Directed Acyclic Graph.
Basic algorithm is recursive depth-first-search with backtracking - see https://www.algotree.org/algorithms/tree_graph_traversal/depth_first_search/all_paths_in_a_graph/
Code in startup code region.
Slight delay after restart due to compiling.

restart

with(GraphTheory)

G := Graph({[1, 2], [1, 4], [2, 3], [2, 5], [3, 5], [4, 3]})

DrawGraph(G, layout = tree, size = [200, 200])
IsAcyclic(G)

GRAPHLN(directed, unweighted, [1, 2, 3, 4, 5], Array(1..5, {(1) = {2, 4}, (2) = {3, 5}, (3) = {5}, (4) = {3}, (5) = {}}), `GRAPHLN/table/1`, 0)

true

infolevel[DAGPaths] := 2

2

paths := DAGPaths(G, 1, 5)

DAGPaths: longest path length is 3

DAGPaths: calculating paths with length between 0 and 3

DAGPaths: calculating 3 paths...

DAGPaths: found expected number of paths

Matrix(%id = 36893490937258087356)

@sursumCorda's graph - see MaplePrimes

A := ImportMatrix(cat(currentdir(), "/matrix.txt"), source = csv)

G := Graph(A)

GRAPHLN(directed, unweighted, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173], Array(1..173, {(1) = {120, 125}, (2) = {77, 107, 121, 133}, (3) = {173}, (4) = {5, 47, 71, 87, 143}, (5) = {9, 32, 60, 120, 137, 138}, (6) = {47}, (7) = {40}, (8) = {105}, (9) = {86, 121, 133}, (10) = {11, 33}, (11) = {42, 69, 91, 118, 163}, (12) = {10, 78, 83, 134, 172}, (13) = {8, 137, 152}, (14) = {5, 45}, (15) = {99, 113}, (16) = {60, 162}, (17) = {39}, (18) = {54, 91, 118}, (19) = {20, 74, 111}, (20) = {9, 93, 138, 149}, (21) = {18, 42, 146}, (22) = {80, 100}, (23) = {26, 42}, (24) = {169}, (25) = {22, 74, 79}, (26) = {69, 163}, (27) = {21, 78, 134, 172}, (28) = {27, 83, 128}, (29) = {}, (30) = {153}, (31) = {5, 8, 140}, (32) = {43, 159}, (33) = {113, 148}, (34) = {39, 94, 103, 128}, (35) = {16, 32}, (36) = {6, 155, 156}, (37) = {34, 86, 98}, (38) = {22, 51, 85, 115, 120, 151}, (39) = {48, 90}, (40) = {17, 166}, (41) = {53, 84}, (42) = {54}, (43) = {55}, (44) = {34, 124, 129}, (45) = {35}, (46) = {9, 51, 152}, (47) = {1, 72, 101, 131}, (48) = {112, 171}, (49) = {54, 127, 147}, (50) = {7, 104}, (51) = {126, 160}, (52) = {25, 38, 46, 141}, (53) = {49, 83, 134}, (54) = {130}, (55) = {102}, (56) = {44, 98}, (57) = {31, 61, 67, 85}, (58) = {59, 71, 156}, (59) = {57, 72, 155}, (60) = {73, 108, 135}, (61) = {5, 74}, (62) = {64, 157, 168}, (63) = {170}, (64) = {63}, (65) = {17, 94, 128, 167}, (66) = {62, 117}, (67) = {25, 115, 120}, (68) = {65, 82, 86, 137}, (69) = {62, 76, 130}, (70) = {84}, (71) = {1, 72}, (72) = {67, 85, 125}, (73) = {28, 84}, (74) = {136, 140}, (75) = {17, 63, 117, 165, 166}, (76) = {64, 169}, (77) = {55, 65, 82, 108, 135, 159}, (78) = {18, 26, 66, 81}, (79) = {2, 51, 80, 105, 152}, (80) = {68, 77, 126, 160}, (81) = {42, 62, 76, 91, 118}, (82) = {27, 144, 145}, (83) = {26}, (84) = {23, 83, 134}, (85) = {74, 154}, (86) = {73, 108}, (87) = {32, 60, 92, 116, 156}, (88) = {165, 166}, (89) = {5, 35, 87}, (90) = {171}, (91) = {103}, (92) = {97, 155}, (93) = {2, 86, 137, 142}, (94) = {3, 15, 33, 66, 90}, (95) = {12, 21, 49, 158}, (96) = {9, 107}, (97) = {13, 141}, (98) = {73, 124, 129}, (99) = {168, 170}, (100) = {138, 152, 154}, (101) = {67, 85, 125}, (102) = {28, 53, 122}, (103) = {88}, (104) = {17, 117, 165, 166}, (105) = {96, 114}, (106) = {19, 61}, (107) = {98}, (108) = {28, 70}, (109) = {95, 123, 135}, (110) = {4, 58, 106}, (111) = {107, 133, 139, 142}, (112) = {15}, (113) = {157}, (114) = {86, 107, 121, 133, 142}, (115) = {13, 140}, (116) = {72, 101, 131}, (117) = {99, 157}, (118) = {130}, (119) = {97, 100, 115, 126}, (120) = {107, 121, 133, 142}, (121) = {56}, (122) = {27, 70, 95, 123}, (123) = {84, 118}, (124) = {11, 18, 81, 94, 128, 146}, (125) = {25, 46, 115}, (126) = {86, 121}, (127) = {24, 76, 130}, (128) = {3, 62, 99}, (129) = {43, 108, 109, 159}, (130) = {50, 164}, (131) = {52, 67, 119, 125}, (132) = {4, 31, 45, 61, 89}, (133) = {98}, (134) = {26, 42}, (135) = {28, 70}, (136) = {93, 96, 114, 138}, (137) = {107, 121, 133}, (138) = {129}, (139) = {138, 149}, (140) = {105, 137, 138}, (141) = {8, 19, 85, 120, 151}, (142) = {56}, (143) = {7, 66, 104, 128, 146}, (144) = {26, 33, 42, 66, 91, 118}, (145) = {41, 70, 95, 123}, (146) = {48, 91, 117, 164}, (147) = {50, 75}, (148) = {62, 117}, (149) = {77, 129}, (150) = {34, 86, 124, 129}, (151) = {20, 74, 111, 152, 154}, (152) = {86, 121}, (153) = {161}, (154) = {93, 105}, (155) = {13, 85, 100, 120}, (156) = {1, 72, 101}, (157) = {29}, (158) = {10, 94}, (159) = {145}, (160) = {37, 56, 150}, (161) = {14, 110, 132}, (162) = {36, 71, 116, 143}, (163) = {54, 127}, (164) = {167}, (165) = {3, 90}, (166) = {90}, (167) = {103}, (168) = {173}, (169) = {50, 75, 164}, (170) = {173}, (171) = {99}, (172) = {23, 81}, (173) = {29}}), `GRAPHLN/table/10`, 0)

paths := CodeTools:-Usage(DAGPaths(G, 30, 29, minlength = 45))

DAGPaths: longest path length is 49

DAGPaths: calculating paths with length between 45 and 49

DAGPaths: calculating 1008252 paths...

DAGPaths: found expected number of paths

memory used=254.33MiB, alloc change=188.31MiB, cpu time=3.42m, real time=3.56m, gc time=296.88ms

Matrix(%id = 36893490937258056028)

NULL

Download BacktrackDAGPaths.mw

DAGPaths:=proc(G::Graph,	# directed acyclic graph - self loops and duplicate edges (if multigraph) are ignored.
			V1, V2,	# start and end vertices to find paths between.
			{minlength::nonnegint := 0, 	# (optional) minimum length of path (measured in number of edges).
			maxlength::nonnegint := -1})	# (optional) maximum length of path - default is length of longestpath.
			# outputs an npaths x (maxlength+1) Matrix (datatype = integer[4]) that contains the paths.
			# entries are positive integers corresponding to the vertices.
			# use infolevel[DAGPaths] := 2 to output additional information. 
	description "finds all paths between two vertices in a directed acyclic graph";
	uses GraphTheory;
	local P, S, A, Adj, n, i, v1, v2, GG, G2, VerticesG, maxpathlength, minlengthi::integer[4], maxlengthi::integer[4],
		maxpaths, maxdeg, pathptr, path, paths, npaths, N, j, src::integer[4], dest::integer[4], newvertices;	
	# check arguments and set up 
	if not IsDirected(G) or not IsAcyclic(G) then error "graph must be directed and acyclic" end if;
	VerticesG := Vertices(G);
	if not member(V1,VerticesG,'v1') then error "Vertex %1 not in graph", V1 end if;
	if V1 = V2 and minlength = 0 then
		return Matrix(1, 1, [1], 'datatype' = integer[4])
	elif V1 = V2 and minlength > 0 then
		userinfo(2, procname, "no paths between %1 and %2 with length greater than %3", V1, V2, minlength); 
		return Matrix(0, 1, 'datatype' = integer[4])
	end if;
	if not member(V2, VerticesG, 'v2') then error "Vertex %1 not in graph", V2 end if;
	if OutDegree(G, V1) = 0 then error "start vertex has no departures" end if;
	if InDegree(G, V2) = 0 then error "end vertex has no arrivals" end if;
	if HasSelfLoop(G) or IsMultigraph(G) then
		userinfo(2, procname, "ignoring duplicate edges and self-loops")
	end if;	
	n := nops(VerticesG);
	GG := UnderlyingGraph(G, 'directed' = true, 'selfloops' = false, 'multigraph' = false);
  	# Delete departures from last vertex
  	if OutDegree(GG, V2) = 1 then
  		DeleteArc(GG, [V2, Departures(G, V2)[]])
  	elif OutDegree(GG, V2) > 1 then
  		DeleteArc(GG, [seq([V2, i], i in Departures(G, V2))])
  	end if;
  	# and delete arrivals to first vertex
  	if InDegree(GG, V1) = 1 then
  		DeleteArc(GG, [V1, Arrivals(G ,V1)[]])
  	elif InDegree(GG, V1) > 1 then
  		DeleteArc(GG, [seq([V1, i], i in Arrivals(G, V1))])
  	end if;
  	# work only on component that V1 is in for path length calc.
  	# (could be ommitted but calc is faster with smaller adjacency matrix)
  	newvertices := select(has, ConnectedComponents(GG), V1)[];
  	if not member(V2, newvertices) then
  		userinfo(2, procname, "no paths between %1 and %2", V1, V2); 
		return Matrix(0, 1, 'datatype' = integer[4])
	end if; 
	# Find length of longest path
	G2 := InducedSubgraph(GG, newvertices);
	Adj := AdjacencyMatrix(G2);
	maxpathlength := nops(BellmanFordAlgorithm(Graph(-Adj), v1, v2)[1]) - 1;
	userinfo(2, procname, "longest path length is %1", maxpathlength);
	if maxlength = -1 then
		maxlengthi := maxpathlength
	else
		maxlengthi := min(maxlength,maxpathlength);
	end if;
	if minlength > maxlengthi then
		userinfo(2, procname, "no paths with minlength %1 greater than maxlength %2", minlength, maxlengthi);
		return Matrix(0, 1, 'datatype' = integer[4])
	else
		minlengthi := minlength
	end if;
	userinfo(2, procname, "calculating paths with length between %1 and %2", minlengthi, maxlengthi);	
	# calculate number of paths from adjacency matrix since # walks = # paths
	P := Adj[v1];
	for i from 2 to minlength do
	P := P.Adj;
	end do:
	S := P:
	for i from minlength + 1 to maxlengthi do
  		P := P.Adj;
  		S := S + P;
	end do:
	maxpaths := S[v2];
	userinfo(2, procname, "calculating %1 paths... ", maxpaths);
	A := op(4,GG):
	# Construct an n x maxdeg Matrix equivalent to op(4,GG) 
	maxdeg := max(map(nops, A));
	N := Matrix(n, maxdeg, 'datatype' = integer[4]):
	for i to n do
		for j to nops(A[i]) do
			N[i,j]:=op(j,A[i])
		end do;
	end do;
	# allocate space and initialize
	src := v1;
	dest := v2;
	path := Vector(maxpathlength + 1, {1 = src}, 'datatype' = integer[4]); # +1 from edges to verts
	paths := Matrix(maxpaths, maxlengthi + 1, 'datatype' = integer[4]);
	npaths := Vector([0], 'datatype' = integer[4]);
	pathptr := 1;
	# call DFS recursively.
	DFS(src, dest, npaths, pathptr, path, paths, minlengthi, maxlengthi, N, maxdeg);
	if npaths[1] = 0 then
		userinfo(2, procname, "no paths between %1 and %2 with lengths between %3 and %4", V1, V2, minlengthi, maxlengthi)
	elif npaths[1] = maxpaths then
		userinfo(2, procname, "found expected number of paths")
	else
		userinfo(2, procname, "found %1 paths - unexpected result", npaths[1])
	end if; 
	# output results
	paths;
end proc:
#
# Compilable recursive Depth-First Search routine - compiled below
#
	DFSM:=proc(src::integer[4], dest::integer[4],
			npaths::Vector(datatype = integer[4]), pathptr::integer[4], path::Vector(datatype = integer[4]),
			paths::Matrix(datatype = integer[4]), minlength::integer[4], maxlength::integer[4],
			N::Matrix(datatype = integer[4]), maxdeg::integer[4])
		local v::integer[4], j::integer[4];
		if src = dest then
  			if pathptr >= minlength + 1 and pathptr <= maxlength + 1 then
    				npaths[1] := npaths[1] + 1;
	    			for j to pathptr do	
					paths[npaths[1], j] := path[j];
				end do;
			end if
		else
			for j to maxdeg do
				v:= N[src, j];
				if v = 0 then break end if;     
				path[pathptr + 1] := v;
				procname(v, dest, npaths, pathptr + 1, path, paths, minlength, maxlength, N, maxdeg);
			end do;
		end if;
		NULL;
	end proc;
#
DFS := Compiler:-Compile(DFSM);

 

restart

Open the Operators palette (or Large Operators) in 2D and choose a symbol - many of them automatically act as infix operators

`&npar;` := proc (R1, R2) options operator, arrow; R2*R1/(R1+R2) end proc

proc (R1, R2) options operator, arrow; R2*R1/(R1+R2) end proc

`&npar;`(X, Y)

Y*X/(X+Y)

Some symbols have predefined meanings, unfortunately including the concatenation operator ||.

I couldn't get the local mechanism to work.

`||` := proc (R1, R2) options operator, arrow; R2*R1/(R1+R2) end proc

Error, attempting to assign to `||` which is protected.  Try declaring `local ||`; see ?protect for details.

`&sqcap;` := proc (R1, R2) options operator, arrow; R2*R1/(R1+R2) end proc

proc (R1, R2) options operator, arrow; R2*R1/(R1+R2) end proc

`&sqcap;`(X, Y)

Y*X/(X+Y)

``

Download infix.mw

(I didn't understand what you meant by simplification if not the above.)

This is fine for simple units but is fairly limited for compound units which are just formatted as Maple expressions with the "*" etc. And for printing formatted strings, symbols such as Angstroms are expressed as their html code, so it would take a lot of work to format unit strings for the general case.

There are lines in the worksheet that are not displayed in Mapleprmes, e.g.,

printf("The voltage is %a %a", NumberUnit(x))

restart

with(Units:-Simple)

NULL

NumberUnit := proc(x)
 local num;
 num := convert(x, unit_free);
 num, eval(x/num, Units:-Unit = (() -> _passed));
end proc:

NULL

x := 5*Unit('V')

5*Units:-Unit(V)

NumberUnit(x)

5, V

printf("The voltage is %a %a", NumberUnit(x))

The voltage is 5 V

NULL

x := 5*Unit('kg'*'m'/('s'))

5*Units:-Unit(kg*m/s)

printf("The momentum is %a %a", NumberUnit(x))

The momentum is 5 kg*m/s

NULL

Download PrintUnits.mw

Here's a second version you may prefer

PrintUnits2.mw

printf("The electric field in base units is %5.2f %s", NumberUnit(x))

The electric field in base units is  5.00 m kg / A s^3

The plot option useunits means the units are interpreted correctly. (And your f2 in 1D was missing a multiplication.)

FunctionUnits.mw

It could probably be made more efficient but I wasn't sure I understood the descriptions and all the assumptions.

Given:
How Can I sort a list of polynomials with parametric coefficients based on the following criteria?
1. Fewer different parameters in the coefficients.
2. If the number of parameters is the same, the lower power of the parameters.
3. If the previous criteria are the same, sentences with parametric coefficients appear later.

Assume: the variables are indexed and the parameters are not.
For the last condition, you mean
x[1]  + a*x[2] is after a*x[1] + x[2] because the a is later (with x[2] not x[1])
and the result depends on the variable indices rather than the order they are wriiten, so
a*x[2  + x[1] is the same as x[1]  + a*x[2] and is after a*x[1] + x[2]
The variable order is as returned by indets, so x[1], x[2] etc, but more complicated if we have x[1] and y[2] etc

restart;

Correct answer for test:

req:=[(a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4],2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]];

[(a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4], 2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]]

test:=[(a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], 2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]];

[(a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], 2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]]

Comparison function

comp:=proc(p1,p2)
  local vars, params, c1, c2, n1, n2, d1, d2;
  vars, params := selectremove(type,indets([p1,p2],name),indexed);
  c1 := [coeffs(p1,vars)];
  c2 := [coeffs(p2,vars)];
  n1 := nops(indets(c1)); # number of parameters in coeffs
  n2 := nops(indets(c2));
  d1 := max(map(degree, c1)); # max degree of parameters
  d2 := max(map(degree, c2));
  member(true,map(x->evalb(nops(indets(x))>0),c1),'pos1'); # pos1 = position of first param
  member(true,map(x->evalb(nops(indets(x))>0),c2),'pos2');
  if n2<n1 then
    false
  elif d2>d1 then
    false
  elif pos2>pos1 then
    false
  else
    true
  end if;
end proc:

Check

sort(test,comp);

[(a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4], 2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]]

req;

[(a+2)*x[1]+3*x[2]-x[3]+(a-2)*x[4], 2*x[1]+2*x[2]-b*x[3]+(c+1)*x[4], (a-1)*x[1]+x[2]+(a+1)*x[3]+(C^2-1)*x[4], (a+b)*x[1]+(c-3)*x[2]+(-b-1)*x[3]+2*x[4]]

NULL

 

Download sort2.mw

seq(NumberTheory:-CalkinWilfSequence(i),i=1..10)

1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5

Here's one way.

Download TabPropQ.mw

(You may want to exclude 1 from k.)

This may be a helpful, though oversimplified example. As for visualization, once you have a solution, each lambda can be plotted in a 3-D plot against two of the parameters for fixed values of the other parameters. It may be possible by some sort of "dimensional" analysis to find combinations of the variables that reduce the number of variables/parameters.

restart;

with(plots):

Symmetry between lambda_2 and lambda__3

Eq2:=lambda__2-lambda__3^2;
Eq3:=lambda__3-lambda__2^2;

-lambda__3^2+lambda__2

-lambda__2^2+lambda__3

If we are interested only in real roots, we want the intersection points between the two plots - from the symmetry we will have lambda__2 = lambda__3 in this case

display(implicitplot(Eq2,lambda__2=-2..2,lambda__3=-2..2,color=red),
        implicitplot(Eq3,lambda__2=-2..2,lambda__3=-2..2,color=blue));

For this case we could have just solved one equation after recognizing lambda__2=lambbda__3

eval(Eq2,lambda__2=lambda__3);
solve(%,lambda__3);
# or:
solve({Eq2,lambda__2=lambda__3});

-lambda__3^2+lambda__3

0, 1

{lambda__2 = 0, lambda__3 = 0}, {lambda__2 = 1, lambda__3 = 1}

In the general case, we have cases where lambda__2 is not equal to lambda__3

ans:=solve({Eq2,Eq3},{lambda__2,lambda__3});
av:=allvalues([ans]);

{lambda__2 = 0, lambda__3 = 0}, {lambda__2 = 1, lambda__3 = 1}, {lambda__2 = -RootOf(_Z^2+_Z+1)-1, lambda__3 = RootOf(_Z^2+_Z+1)}

[{lambda__2 = 0, lambda__3 = 0}, {lambda__2 = 1, lambda__3 = 1}, {lambda__2 = -1/2-((1/2)*I)*3^(1/2), lambda__3 = -1/2+((1/2)*I)*3^(1/2)}], [{lambda__2 = 0, lambda__3 = 0}, {lambda__2 = 1, lambda__3 = 1}, {lambda__2 = -1/2+((1/2)*I)*3^(1/2), lambda__3 = -1/2-((1/2)*I)*3^(1/2)}]

simplify(eval([Eq2,Eq3],av[1][3]));
simplify(eval([Eq2,Eq3],av[2][3]));

[0, 0]

[0, 0]

Stepwise solve

lambda__3_1,lambda__3_2:=solve(Eq2,lambda__3);

lambda__2^(1/2), -lambda__2^(1/2)

eval(Eq3,lambda__3=lambda__3_1); # more complicated equation to solve in last step
solve(%,lambda__2);

-lambda__2^2+lambda__2^(1/2)

0, 1

eval(Eq3,lambda__3=lambda__3_2); # more complicated equation to solve in last step
solve(%,lambda__2);

-lambda__2^2-lambda__2^(1/2)

0, -1/2-((1/2)*I)*3^(1/2), -1/2+((1/2)*I)*3^(1/2)

NULL

Download symmetry.mw

Heres another approach for more recent Maple versions in 1-D only. It could be worked up into a procedure as @mmcdara did, but I am short of time now. I think it should be reasonably efficient but I didn't do any tests.

restart

M := Matrix(4, 3, {(1, 1) = 34, (1, 2) = 67, (1, 3) = 1, (2, 1) = 35, (2, 2) = 80, (2, 3) = 1, (3, 1) = 45, (3, 2) = 45, (3, 3) = 2, (4, 1) = 56, (4, 2) = 99, (4, 3) = 2})

Search column 3 for values 2 and return corresponding rows

M[[for i to upperbound(M)[1] do `if`(M[i,3]=2,i,NULL) end do]];

Matrix(2, 3, {(1, 1) = 45, (1, 2) = 45, (1, 3) = 2, (2, 1) = 56, (2, 2) = 99, (2, 3) = 2})

Search row 3 for values 45 and return corresponding columns

M[..,[for i to upperbound(M)[2] do `if`(M[3,i]=45,i,NULL) end do]];

Matrix(4, 2, {(1, 1) = 34, (1, 2) = 67, (2, 1) = 35, (2, 2) = 80, (3, 1) = 45, (3, 2) = 45, (4, 1) = 56, (4, 2) = 99})

NULL

Download search.mw

As @Carl Love says, it is common to get these small imaginary parts. They can be removed with fnormal and simplify(...,zero). Your case is unusual in that the digits for fnormal needs to be significantly different from the digits for the calculation - I don't recall ever having to use the digits option to fnormal before. Presumably the inaccuracies in the dilog, etc functions accumulate errors.

[Edit: the imaginary part looks suspiciously like Pi times a power of 10, so perhaps there is more going on here.]

restart;

with(Units) :

c := 299792458*Unit(m)/Unit(s) :
h := 662607015*10^(-8)*10^(-34)*Unit(J)/Unit(Hz) :
k := 1380649*10^(-6)*10^(-23)*Unit(J)/Unit(K) :
lambda_V_max := 750*Unit(nm) :
lambda_V_min := 380*Unit(nm) :
T_Sol := 5772.0*Unit(K) :
T0_Sol := 5772*Unit(K) :

M := (T, lambda_min, lambda_max) -> Pi*int(2*c^2*h/((exp(c*h/(k*lambda*T)) - 1)*lambda^5), lambda = lambda_min .. lambda_max) :
sigma := 2*GAMMA(4)*Pi*Zeta(4)*k^4/(c^2*h^3) :

M_inf := (T) -> T^4*sigma :

M_Sol := M_inf(T_Sol) :
M0_Sol := M_inf(T0_Sol) : # 6.2938592470335950467548474587300E7*Unit(W)/Unit(m)^2

exact:=M(T0_Sol, lambda_V_min, lambda_V_max): # this is an exact value (zero uncertainty)

Automatically loading the Units[Simple] subpackage
 

approx:=evalf[16](exact);

(27551199.57168703-0.3141592653589793e-5*I)*Units:-Unit(kg/s^3)

fnormal should convert the imaginary part to 0.*I if it is just numerical roundoff - using the same number of digits does not do this

 - suggests the many complicated functions have led to more roundoff than usual.

fnormal(approx,16);

(27551199.57168703-0.3141592653589793e-5*I)*Units:-Unit(kg/s^3)

Try doing the calc to lower precision. Now the zero imaginary part may be removed with simplify/zero

fnormal(approx,7);
simplify(%,zero);

(0.2755120e8-0.*I)*Units:-Unit(kg/s^3)

0.2755120e8*Units:-Unit(kg/s^3)

approx:=evalf[32](exact);
fnormal(approx,23);
simplify(%,zero);

(27551199.571700602410253741952027+0.50265482457436691815402294132472e-21*I)*Units:-Unit(kg/s^3)

(27551199.571700602410254+0.*I)*Units:-Unit(kg/s^3)

27551199.571700602410254*Units:-Unit(kg/s^3)

NULL

Download fnormal.mw

for m from 0 to 5 do
  printf("% 5d\n",<seq(binomial(m,i),i=0..m)>);
end do;
   

    1
    1     1
    1     2     1
    1     3     3     1
    1     4     6     4     1
    1     5    10    10     5     1

As in @nm's answer, I'm not quite there yet, but have resolved the issue of which is the correct root

restart;

expected:=(1+cos(arctan(3/4)/3))/3;evalf(%);

1/3+(1/3)*cos((1/3)*arctan(3/4))

.6590276223

alias(alpha=RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1));

alpha

evalf(alpha);

.1090390091

alpha1:=simplify(convert(alpha,radical));
evalf(%);

(1/72)*((36*I)*(1/270+(1/360)*I)^(2/3)*3^(1/2)-36*(1/270+(1/360)*I)^(2/3)-I*3^(1/2)+24*(1/270+(1/360)*I)^(1/3)-1)/(1/270+(1/360)*I)^(1/3)

.1090390092-0.2069494425e-10*I

As written (both index=1), it is the wrong root to correspond to the expected result.

u1 := RootOf(4*_Z^2 + (4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1) - 4)*_Z + 4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1)^2 - 4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1) + 1);
evalf(%);

RootOf(4*_Z^2+(4*alpha-4)*_Z+4*alpha^2-4*alpha+1)

.2319333685

We want index=2 of the outer RootOf, but I copied here, which is cheating

RootOf(4*_Z^2 + (4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1) - 4)*_Z + 4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1)^2 - 4*RootOf(60*_Z^3 - 60*_Z^2 + 15*_Z - 1) + 1,index=2);
evalf(%);

RootOf(4*_Z^2+(4*alpha-4)*_Z+4*alpha^2-4*alpha+1, index = 2)

.6590276225

u2:=subs(alpha=a,u1);
rt1,rt2:=allvalues(u2);

RootOf(4*_Z^2+(4*a-4)*_Z+4*a^2-4*a+1)

-(1/2)*a+1/2+(1/2)*(-3*a^2+2*a)^(1/2), -(1/2)*a+1/2-(1/2)*(-3*a^2+2*a)^(1/2)

We want rt1

evalf(eval(rt1,a=alpha1));
evalf(eval(rt2,a=alpha1));

.6590276224-0.381382510e-11*I

.2319333684+0.2450876934e-10*I

u4:=simplify(eval(rt1,a=alpha1));
evalf(%);

1/3+(1/12)*cos((1/3)*arctan(3/4))+(1/12)*(cos((2/3)*arctan(3/4))+2-3^(1/2)*sin((2/3)*arctan(3/4)))^(1/2)*3^(1/2)+(1/12)*sin((1/3)*arctan(3/4))*3^(1/2)

.6590276224

Stuck on the last step...

 

Download RootOf.mw

You can work around this by making a new context for the are unit in which any SI prefix is allowed.

restart

with(Units[Standard])

A := Unit('ha')

Units:-Unit(ha)

convert(A, units, Unit(a))

100*Units:-Unit(a)

convert(A, units, Unit(Pa))

Error, (in convert/units) unable to convert `ha` to `Pa`

a and ha are defined as "one-offs" with prefix=none, i.e.,can't use prefixes.

Units:-GetUnit(a)

are, abbreviations = {}, plural = are, default = true, spellings = {are}, prefix = none, abbreviation = none, spelling = are, conversion = 100*metre[SI]^2, context = SI, symbols = {a}, symbol = a

Units:-GetUnit(ha)

hectare, abbreviations = {}, plural = hectares, default = true, spellings = {hectare, hectares}, prefix = none, abbreviation = none, spelling = hectare, conversion = 10000*metre[SI]^2, context = SI, symbols = {ha}, symbol = ha

But if we define a new context "realestate" then we can define a again with a different context in which we can use any prefix

Units:-UseContexts(realestate)

Units:-AddUnit(are, context = realestate, prefix = SI, conversion = are)

B := Unit(ha[realestate])

Units:-Unit(ha)

convert(B, units, Unit(Pa[realestate]))

(1/10000000000000)*Units:-Unit(Pa)

NULL

Download Areas.mw

First 21 22 23 24 25 26 27 Last Page 23 of 81