What is wrong in this command "series(diff(f(z), z), z = 1, 2)" in Maple? - series

Assume f(z) is an arbitrary function of z. In Maple, if we want to get the series expansion of diff(f(z),z) at z=0, we can use
series(diff(f(z), z), z = 0, 2)
The output is "(D(f))(0)+...". However, we cannot obtain the series expansion of diff(f(z),z) at z=1 by
series(diff(f(z), z), z = 1, 2)
The output is "Error, (in PDEtools/useD/diff_to_D) invalid input: diff received z+1, which is not valid for its 2nd argument." What is wrong, and how to get the series expansion of an expression that contains derivatives of a function such as diff(f(z),z)?

It looks like a bug.
Workarounds might include,
series(D(f)(z), z = 1, 2);
/ 2\
D(f)(1) + ##(D, 2)(f)(1) (z - 1) + O\(z - 1) /
or (with a different expansion order option),
MultiSeries:-series(diff(f(z), z), z = 1, 3);
/ 2\
D(f)(1) + ##(D, 2)(f)(1) (z - 1) + O\(z - 1) /

Related

dynamic selection for linear interpolation

I have a function, which i called InterpolLinear
Function InterpolLinear(x, xvalues, yvalues)
x1 = Application.WorksheetFunction.Index(xvalues, Application.WorksheetFunction.Match(x, xvalues, 1))
x2 = Application.WorksheetFunction.Index(xvalues, Application.WorksheetFunction.Match(x, xvalues, 1) + 1)
y1 = Application.WorksheetFunction.Index(xvalues, Application.WorksheetFunction.Match(y, xvalues, 1))
y2 = Application.WorksheetFunction.Index(xvalues, Application.WorksheetFunction.Match(y, xvalues, 1) + 1)
InterpolLinear = y1 + (y2 - y1) * (x - x1) / (x2 - x1)
EndFunction
I want the function to automatically select all the x values and all the y values, without having to adjust it manually. I can have 10 x and y values, or 100. The function is working ok, but i have to adjust the selection manually.
I took 2 screenshots.
You just need to define two named ranges which adjust dynamically. Add a named range, say x_values and define it by
=$E$1:INDEX($E:$E;MATCH(1000000;$E:$E;1))
Do the same for y_values, changing the references to column F. Then
=LinInterp(D1;x_values;y_values)
note, your images used the function LinInterp and your code uses the function InterpolLinear, so just make sure you're consistent
Also, you can assign your variables more simply, for example:
x1 = xvalues.Cells(Application.Match(x, xvalues, 1),1).Value

Scaling up a tile-map smoothly?

I'm making a mod for some game, and I'm using a base tile-map that I want to be scaleable to a bigger map. However, when I just use a "nearest-neighbour" kind of scaling the map will have hard square edges. I want to prevent this.
So I have a tilemap, something like this:
- - X -
- X X X
X X X X
X X - -
With my current scaling I get something like:
- - - - X X - -
- - - - X X - -
- - X X X X X X
- - X X X X X X
X X X X X X X X
X X X X X X X X
X X X X - - - -
X X X X - - - -
Which has some hard edges as you can see. I would like them to be more smooth:
- - - - X X - -
- - - X X X X -
- - X X X X X X
- X X X X X X X
X X X X X X X X
X X X X X X X X
X X X X X X - -
X X X X - - - -
I wasn't sure what to call this, so my search didn't turn up much.
How can I do something like this?
Note that there are several different kinds of tiles, and no in-between tile types.
So I played around a bit myself, and found something that seems to work quite well.
Here's what I do (Lua):
--First get the cells you're between (x and y are real numbers, not ints)
local top = math.floor(y)
local bottom = (top + 1)
local left = math.floor(x)
local right = (left + 1)
--Then calculate weights. These are basically 1 - the distance. The distance is scaled to be between 0 and 1.
local sqrt2 = math.sqrt(2)
local w_top_left = 1 - math.sqrt((top - y)*(top - y) + (left - x)*(left - x)) / sqrt2
local w_top_right = 1 - math.sqrt((top - y)*(top - y) + (right - x)*(right - x)) / sqrt2
local w_bottom_left = 1 - math.sqrt((bottom - y)*(bottom - y) + (left - x)*(left - x)) / sqrt2
local w_bottom_right = 1 - math.sqrt((bottom - y)*(bottom - y) + (right - x)*(right - x)) / sqrt2
--Then square these weights, which makes it look better
w_top_left = w_top_left * w_top_left
w_top_right = w_top_right * w_top_right
w_bottom_left = w_bottom_left * w_bottom_left
w_bottom_right = w_bottom_right * w_bottom_right
--Now get the codes (or types) of the surrounding tiles
local c_top_left = decompressed_map_data[top % height][left % width]
local c_top_right = decompressed_map_data[top % height][right % width]
local c_bottom_left = decompressed_map_data[bottom % height][left % width]
local c_bottom_right = decompressed_map_data[bottom % height][right % width]
--Next calculate total weights for codes
-- So add together the weights of surrounding tiles if they have the same type
local totals = {}
add_to_total(totals, w_top_left, c_top_left) --see below for this helper func
add_to_total(totals, w_top_right, c_top_right)
add_to_total(totals, w_bottom_left, c_bottom_left)
add_to_total(totals, w_bottom_right, c_bottom_right)
--Lastly choose final code, which is the tile-type with the highest weight
local code = nil
local weight = 0
for _, total in pairs(totals) do
if total.weight > weight then
code = total.code
weight = total.weight
end
end
return terrain_codes[code]
-- Helper function
local function add_to_total(totals, weight, code)
if totals[code] == nil then
totals[code] = {code=code, weight=weight}
else
totals[code].weight = totals[code].weight + weight
end
end
And voila. This select an exact tile-type for any x/y value even when they are not integers, thus making it possible to scale your grid. I'm not sure if there are better ways, but it works and looks good. In the end I also added some random number to the weights, to make the edges a little less straight which looks better in Factorio when scaling very high.

How can I write a code to define a range insdide a loop that will change its size?

I need to use two Loops and the easy part is to count how many times does a "submodul" repeats in a defined and known range ("B3","B18"), this means the quantity of elements each submodul has. The difficult part comes when trying to count how many times does a "position" repeats for each different "submodul", this is because the amount of elements of each "submodul" is different so I have to adjust a range in a especial Loop to calculate how many times does a specific element (=Position) repeats within a "submodul".
The specific part that I need help with is the following:
positionrepetition = Application.CountIf(Worksheets("Sheet2").range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), position)
If I can manage to write it in a correct format I believe it will work. The problem is that normally I only use the range function when I know that the range is fixed or known, it doesn´t have to be calculated. I normally write for example: Range("A1","F10").Select
As you can see this is a fixed range, so I imagined that instead of using the format of Range("A1", "F10") I could use the range function with the arguments ("Cells(1,1)","Cells(10,6)"). Please correct me if I´m wrong.
Here is the rest of the code for the Loop.
For x = 0 To numberofparts
If Cells(3 + x, 18) = "1" Then
submodul = Cells(3 + x, 2).Value
submodulrepetition = Application.CountIf(Worksheets("Sheet2").range("B3", "B18"), submodul)
For y = 1 To submodulrepetition
position = Cells(3 + x + y - 1, 3).Value
positionrepetition = Application.CountIf(Worksheets("Sheet2").range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), position)
Next
Else
End If
x = x + submodulrepetition - 1
Next
To explain a little more, all data is gathered from Excel Sheets:
-All Information is gathered from a Excel sheet
-The "submodules" are in column B and they are arranged in numerical order. Every submodul repeats in this column as many elements it has.
-The "positions" (elements of the submodules) are in column C and can also repeat in the same column and even in other "Submodul"s.
All help will be appreciated and I thank you in advance.
Alejandro Farina
Change your line:
positionrepetition = Application.CountIf(Worksheets("Sheet2").Range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), Position)
With :
positionrepetition = Application.CountIf(Worksheets("Sheet2").Range(Cells(3 + x + y - 1, 3), Cells(3 + x + y - 1 + submodulrepetition, 3), Position))
If the Range is going to Change by Column/Row use the following code to get the end of column or row:
Dim GetColEnd, GetRowEnd As Integer
GetColEnd = Sheets("Sheet_Name").Cells(1, .Columns.Count).End(xlToLeft).Column
GetRowEnd = Sheets("Sheet_Name").Cells(Rows.Count, 1).End(xlUp).Row
Use the GetColEnd GetRowEnd in your Range function for flexible Column\Row for example as follows:
Sheets("Sheet_Name").Range(Cells(1,1),Cells(GetRowEnd,GetColEnd)

Storing and processing range values in an array

While storing range values as a variant and looping through them i'm having trouble actually changing the value of, for example,
valsf(i, h) = (valsf(i - 1, h) + valsf(i + 1, h)) / 2
It will only change when I make it
Cells(i, h) = (valsf(i - 1, h) + valsf(i + 1, h)) / 2
Why is this?

Finding a point on a diagonal line when i have the start point and end point of the Line

Hi am looking for some help
I have a Diagonal line drawn on a picture box on my forum and i need to know if the user has clicked the line
I have the Start point and End Point of the Line and the mouse x,y location
So i basically need to find out if the x,y of the mouse is on the line.
can anyone help?
Thanks
Example: Line Start point (A) is (0, 0), END point (B) is (10, 5).
Slope of line is therefore:
m(slope) = (y2 - y1) / (x2 - x1)
= (5 - 0) / (10 - 0)
= 5 / 10
= 0.5
To check if your point(x,y) (C) is on the line it must have the same slope from A->C and C->B. so do the same calculation again. Say point is (4, 2)
m(AC) = (2 - 0) / (4 - 0)
= 2 / 4
= 0.5
m(CB) = (5 - 2) / (10 - 4)
= 3 / 6
= 0.5
Therefore this point would be on line AB.
If point was (20, 10)
m(AC) = (10 - 0) / (20 - 0)
= 10 / 20
= 0.5
However:
m(CB) = (5 - 10) / (10 - 20)
= -5 / -10
= -0.5
Similarly if point was (2, 2)
m(AC) = (2 - 0) / (2 - 0)
= 2 / 2
= 1
m(CB) = (5 - 2) / (10 - 2)
= 3 / 8
= 0.375
So for a point to be on a line m(AB) == m(AC) == m(CB)
You may have a bit of work arounds to perform as you may not be able to get decimal values, and your line may be more than one pixel in width, but these basic principles should see you through.
Given two points, (2,4) and (-1,-2) determine the slope intercept form of the line.
1. Determine the slope
y1-y2 4-(-2) 6
----- = ------= --- = 2 = M
x1-x2 2-(-1) 3
2. To slope intercept form using one of the original points and slope from above.
(y - y1) = m(x - x1)
(y - 4) = 2(x - 2)
y - 4 = 2x - 4
y = 2x + 0 (0 is y intercept)
y = 2x (y = 2x + 0) is in slope intercept form
3. To determine if a point lies on the line, plug and chug with the new point.
new point (1,2) does y = 2x? 2 = 2(1) = true so (1,2) is on the line.
new point (2,2) does y = 2x? 2 = 2(2) = false so (2,2) is not on the line.
In your original problem you said line, but I think you might mean line segment. If you mean the latter you will also need to verify that the new x and y are within the bounds of the given segment.
The code will look something like this
Dim pta As Point = New Point(2, 4)
Dim ptb As Point = New Point(-1, -2)
Dim M As Double
If pta.X - ptb.X <> 0 Then
M = (pta.Y - ptb.Y) / (pta.X - ptb.X)
End If
'(y - pta.y) = M(x - pta.x)
'y - pta.y = Mx - m(pta.x)
'y = Mx - M(pta.x) + pta.y
Dim yIntercept As Double = (-M * pta.X) + pta.Y
Dim ptN1 As Point = New Point(1, 2)
Dim ptN2 As Point = New Point(2, 2)
If ptN1.Y = (M * (ptN1.X)) + yIntercept Then
Stop
Else
Stop
End If
If ptN2.Y = (M * (ptN2.X)) + yIntercept Then
Stop
Else
Stop
End If